본문으로 건너뛰기

SOLAPI 앱스토어에 내 앱 등록하기 1. 솔라피 OAuth2 인증

· 약 10분
Eden Cha

솔라피 서드파티 개발자를 위한 앱 등록부터 개발, 배포까지 직접 예제를 제작하여 앱스토어 전반에 관한 가이드를 제공합니다.

앱 기획하기

먼저 기획 단계에서는 앱 등록의 목적에 따라, 최종 사용자를 고려하여 기획을 진행합니다. 이번 가이드에서는 잔액과 발신번호를 확인할 수 있고 특정 수신인에게 문자를 발송할 수 있는 간단한 데스크탑용 프로그램을 개발 후 앱을 등록하겠습니다. 앱 개발전에 미리 솔라피에 앱을 생성하겠습니다.

앱 생성하기

솔라피 앱 관리 페이지 (https://solapi.com/me/apps)에 접속하여 우측 상단 앱생성 버튼을 클릭 후 앱 이름을 입력하면 새로운 앱을 생성할 수 있습니다. 앱을 생성하면 목록에서 확인할 수 있고 목록의 행을 클릭하면 앱에 대한 자세한 정보를 조회하거나, 수정, 수익금 설정이 가능합니다.

앱 리스트 페이지 상단

앱 리스트 페이지

앱 개발하기

NodeJS 및 javascript와 Electron에 대한 이해가 있다는 가정에서 각각에 대한 설명은 생략합니다.

http 요청이 가능한 다른 언어나 패키지를 이용하여 개발할 수 있습니다. 해당 예제는 웹 서버와 데이터베이스가 구성된 환경을 필요로 합니다. 서버는 Express, 데이터베이스는 MongoDB를 이용했지만 개발 환경은 자유롭게 구성해도 좋습니다.

마찬가지로 서버와 데이터베이스 구성이 목적인 글이 아니므로 환경을 꾸미는 자세한 설명은 생략합니다.

인증과 정보 조회를 거쳐 최종적으로 문자 발송이 가능한 간단한 기능을 구성할 예정이며, 사용자 인증을 위한 솔라피 OAuth2의 Authorization Code Grant Type 인증 방식을 이용합니다.

솔라피 OAuth2에 대한 설명이 필요한경우 아래 문서를 참조하세요.

https://docs.solapi.com/authentication/oauth2

전체 예제 코드는 아래 저장소에서 확인할 수 있습니다.

https://github.com/edencha/solapi-desktop-app-demo

OAuth2로 솔라피 회원 인증하기

앱을 사용하는 사용자의 보호된 데이터 조회와 처리를 위해 사용자의 권한을 승인받아야 합니다.

OAuth2 인증 방식을 통해 JWT 형태의 액세스 토큰을 발행 받아 앱 사용자의 데이터에 접근할 수 있습니다.

OAuth2 인증

가장 먼저, 클라이언트는 사용자에게 권한을 요청해야 합니다.

https://api.solapi.com/oauth2/v1/authorize

위 API 리소스 주소에 client_id, response_type, redirect_uri, scope, state의 총 5가지 쿼리 파라미터를 추가하여 GET 요청 시, 내 앱에 권한을 제공할 수 있는 페이지로 이동합니다.

각 파라미터에 대한 자세한 설명은 https://developers.solapi.com/references/authentication/oauth2-3/oauth2 에서 확인할 수 있습니다.

앱 정보 페이지

솔라피 앱 정보 조회 페이지에서 client_id, redirect_uri의 파라미터에 들어갈 값을 확인합니다.

앱 정보 페이지에서 입력한 Redirect URI로 코드가 발급되므로 자신의 서비스 도메인을 입력하도록 합니다. e.g) https://my-service.com/code

로그인 버튼 클릭 시 권한 요청 페이지를 표시해야 합니다.

index.html
<button type="button" onclick="onClickLogin()">로그인</button>
renderer.js
function onClickLogin() {
ipcRenderer.send('request-login')
}
main.js
const config = {
apiHost: 'http://127.0.0.1:3000',
solapiHost: 'https://api.solapi.com',
client_id: 'CIDIVP82EOCJX1WO',
response_type: 'code',
redirect_uri: 'http://127.0.0.1:3000/token',
scope: 'users:read message:write senderid:read'
}

ipcMain.on('request-login', async e => {
// 권한 승인 페이지 url 생성
const authorizePage = config.solapiHost + '/oauth2/v1/authorize?'
const state = uniqid()
const query = {
client_id: config.client_id,
response_type: config.response_type,
redirect_uri: config.redirect_uri,
scope: config.scope,
state
}
const loadUrl = authorizePage + qs.stringify(query)
child.loadURL(loadUrl)
})

이제 로그인 버튼을 클릭하면 아래의 도메인이 생성되어, 사용자에게 권한 요청 페이지를 보여줍니다.

https://api.solapi.com/oauth2/v1/authorize?client_id=CIDIVP82EOCJX1WO&response_type=code&redirect_uri=http://127.0.0.1:3000/token&scope=cash:read senderid : 메시지 읽기 : 쓰기 및 상태 = 4n5pxq24kpiob12og9

위 URL로 이동 시 솔라피에 로그인이 되어있는 상태라면, 곧 바로 권한 승인페이지가 표시되지만, 로그인이 필요한 경우 로그인 후 권한 승인 페이지로 이동합니다.

scope는 사용자에게 요청하는 권한을 뜻합니다. 사용자가 허용한 scope정보는 토큰에 포함되고, 토큰 이용 시 포함된 권한의 범위를 벗어난 데이터를 요청하는 경우에는 권한이 없다는 오류가 발생합니다.

토큰을 생성할 때 앱에서 사용하는 필요 권한을 적절히 포함해야 합니다.

앱 정보 페이지에서 사용할 권한을 미리 정의합니다.

scope 파라미터 입력 시 여러개를 사용해야 하는 경우 공백으로 구분합니다. 지원하는 권한 종류와 설명을 확인하려면 솔라피 문서를 참조하세요. https://docs.solapi.com/authentication/oauth2-scope#scope-%EB%AA%A9%EB%A1%9D

예로 scope의 종류 중 ‘message:write’는 문자 발송 등, 메시지 서비스에 관한 쓰기 권한을 발행하는 토큰에게 부여합니다.

사용자가 보는 권한 승인 페이지

사용자가 로그인 후 권한 부여를 승인하면, 앱 생성 시 설정한 redirect_uri로 code와 state가 쿼리 파라미터 형태로 전달되고, 서에서는 이 code와 클라이언트 인증 정보(client_id, client_secret)를 통해 솔라피 인증 서버에 요청하여 최종적으로 액세스 토큰을 발행 받습니다.

다음은 redirect_uri인 http://127.0.0.1:3000/token에 접근하면 실행되는 서버사이드의 핸들러 코드입니다.

server.js
app.use('/token', async (req, res, next) => {
try {
const code = req.query.code
const state = req.query.state
const requestUrl = 'https://api.solapi.com/oauth2/v1/access_token'
const reqBody = {
grant_type: 'authorization_code',
client_id: 'CIDIVP82EOCJX1WO',
client_secret: '{your_client_secret}',
redirect_uri: 'http://127.0.0.1:3000/token',
code
}
const { data } = await axios.post(requestUrl, reqBody)
AccessToken.create({
accessToken: data.access_token,
state
})
.then(data => {
res.redirect('/login-success')
})
.catch(error => {
res.redirect('/login-fail?message=' + error.message)
})
} catch (error) {
next(error)
}
})

앱 정보 페이지에서 조회할 수 있는 client_secret은 앱 생성 시 최초로 생성되고, 다시 조회할 수 없으므로 잘 보관합니다. 만약 잃어버린 경우 재생성해야 합니다. 클라이언트 사칭 등으로 인한 피해를 막기 위해 client_secret은 외부에 노출되지 않도록 반드시 서버 사이드에 존재해야 합니다.

필수 사항은 아니지만 액세스 토큰 역시 데이터베이스 혹은 세션에 저장을 권장합니다. 이때 별도의 TTL을 설정하여 일정 시간이 지나면 자동으로 파기되도록 하면 더 안전합니다. (Refresh Token을 이용한 로그인 유지 기능은 이 가이드에서는 다루지 않습니다.)

이제 발행 받은 액세스 토큰을 이용해서 사용자의 보호된 데이터를 요청할 수 있습니다. 다음 글에서는 액세스 토큰과 솔라피 API를 사용한 데이터 조회 방법을 설명합니다.