OAuth 연동하기
모두싸인의 OAuth 기능은 모두싸인과 외부 서비스 사이의 승인 상호작용을 통해, 외부 애플리케이션이 사용자를 대신하여 리소스에 접근할 수 있도록 하는 기능입니다. 표준 OAuth2.0 Authorization Code Grant 방식을 지원합니다.
모두싸인의 기능을 외부에서 제공하기를 원하는 서비스는 OAuth 기능을 이용할 수 있습니다.
고객은 외부 서비스가 모두싸인의 리소스에 접근할 수 있도록 권한을 허가할 수 있으며, 허가받은 범위에서 서비스는 모두싸인의 리소스에 접근하여 고객을 대신해 기능을 이용할 수 있습니다.
애플리케이션 생성
OAuth 기능을 사용하기 위해서는 먼저 애플리케이션을 만들어야 합니다.
애플리케이션은 다음 정보를 가집니다.
정보 | 설명 |
---|---|
기본 정보 | - 애플리케이션 이름 - 애플리케이션 소유자: 모두싸인 회원 정보(이름, 이메일) - 홈페이지 주소 (선택) - 프로필 이미지 (선택) |
Redirect URIs | OAuth 인가 진행 후, 리디렉션을 통해 authorization code를 전달 받을 수 있는 URI를 지정합니다. 배열로 다수의 URI를 지정할 수 있습니다. 해당 목록에 포함되지 않는 redirect_uri가 인가 페이지로 전달 될 경우 에러를 일으킵니다. |
허용 IP 목록 (선택) | 인가를 요청하는 서버의 IP를 제한할 수 있습니다. 비워둘 경우 요청 서버 IP에 대한 별도의 제한 없이 요청이 가능합니다. 배열로 다수의 IP를 지정할 수 있습니다. |
현재 애플리케이션 생성은 모두싸인 고객센터를 통해서만 가능합니다.
OAuth 기능 이용에 대한 문의는 고객센터로 연락해주세요.
애플리케이션을 생성하면 애플리케이션 식별 및 인증에 사용되는 clientId
와 clientSecret
을 발급합니다.
애플리케이션용 API를 인증하기 위해서는 clientId
와 cilentSecret
을 body에 전달하여 인증할 수 있습니다.
clientSecret
을 절대 공유하지 마세요. 애플리케이션의 password 역할을 합니다.
또한clientSecret
을 클라이언트에서 사용하는 것은 보안에 취약하므로 서버사이드에서 다루어 주세요.
인가 요청 및 인가 코드(Authorization code) 발급
OAuth 연동을 위해 유저에게 애플리케이션에 대한 인가를 얻어야 합니다.
고객을 "인가 요청 페이지" 로 이동시켜 인가를 진행할 수 있습니다. "인가 요청 페이지" 의 주소와 필요한 정보는 아래와 같습니다.
인가 요청 페이지 최종 URL 예시
https://app.modusign.co.kr/oauth/authorize?response_type=code&client_id=01FQE43XG5KAAA3ZKL4DFQ1S66&state=8759367&redirect_uri=https%3A%2F%2Fsite.com%2Fcallback
인가 요청 페이지 기본 URL
https://app.modusign.co.kr/oauth/authorize
쿼리 파라미터
query 파라미터 명 | 설명 |
---|---|
response_type | 인가 획득 방식 값을 code 로 고정해주세요. |
client_id | 인가를 요청하는 애플리케이션의 ID |
state | CSRF를 방지하기 위해 사용하는 Client 측 인증값 (URL 인코딩 필요) 임의의 문자열을 입력해 주세요. 인가후 이동할 페이지에 파라미터로 다시 전달됩니다. 자신이 보낸 요청에 대한 응답인지 판별할 수 있습니다. |
redirect_uri | 인가를 통해 Authorization Code를 발급받은 후 이동될 페이지 URI (URL 인코딩 필요) 애플리케이션 설정의 Redirect URIs 목록에 해당되지않는 uri가 요청될 경우 에러가 발생합니다. |
"인가 요청 페이지"는 모두싸인 로그인이 필요합니다.
고객이 모두싸인에 로그인 되어 있지않다면 로그인 페이지로 이동하며 로그인 후에 "인가 요청 페이지" 로 이동합니다.
유저가 연결하기 버튼을 클릭해 인가를 허용하면 redirect_uri
로 이동해 인가 코드(Authorization code)가 함께 전달됩니다.
전달 예시
https://site.com/callback?code=94228db4tt12&state=8759367
- code: 해당 유저에게 발급한 인가 코드(Authorization code)
- state: 인가 요청 페이지에 쿼리 파라미터로 전달한 state 입니다. 해당 state를 검증해 CSRF를 방지할 수 있습니다.
연결하기 취소 버튼 클릭 시 redirect_uri
로 이동하며 queryparam 으로 error=access_denied 메시지가 전달 됩니다.
Logout
연결을 취소하거나, 연결 후 고객 상태에 따라서 다른 아이디로 로그인을 유도하는 등의 작업을 위해 로그아웃이 필요한 경우 아래의 주소 호출 시 브라우저에서 모두싸인 계정이 로그아웃 처리 됩니다.
https://app.modusign.co.kr/signout?redirectTo=${encodeURIComponent(https://modusign.co.kr)}
redirectTo 에 지정되는 URL은 위의 예시와 같이 인코딩이 필요하며, redirectTo 속성을 설정하지 않는다면 모두싸인 로그인 페이지로 이동 합니다.
OAuth 토큰 발급 및 인증하기
인가 코드를 이용한 토큰 발급
인가 요청의 응답으로 전달된 인가 코드(Authorization code)를 이용하여 실제 API 요청에 활용할 OAuth access_token
을 발급 받을 수 있습니다.
access_token
발급에는 토큰 발급 및 갱신 API를 사용합니다.
요청하기
요청 중 grant_type
에는 "authorization_code" 값을 넣어 요청해 주세요.
redirect_uri
값은 인가 코드 발급에 사용되었던 redirect_uri를 입력해주세요.
curl --request POST \
--url https://api.modusign.co.kr/oauth/token \
--header 'Accept: application/json' \
--header 'Content-Type: application/json' \
--data '
{
"grant_type": "authorization_code",
"client_id": "CLIENT-ID",
"client_secret": "CLIENT-SECRET",
"code": "AUTHORIZATION-CODE",
"redirect_uri": "http://example.com"
}
'
const fetch = require('node-fetch');
const url = 'https://api.modusign.co.kr/oauth/token';
const options = {
method: 'POST',
headers: {Accept: 'application/json', 'Content-Type': 'application/json'},
body: JSON.stringify({
grant_type: 'authorization_code',
client_id: 'CLIENT-ID',
client_secret: 'CLIENT-SECRET',
redirect_uri: 'http://example.com',
code: 'AUTHORIZATION-CODE',
refresh_token: '',
})
};
fetch(url, options)
.then(res => res.json())
.then(json => console.log(json))
.catch(err => console.error('error:' + err));
응답
{
"access_token": "액세스 토큰(JWT)",
"refresh_token": "리프레시 토큰(JWT)",
"token_type": "Bearer",
"expires_in": 1800
}
- 액세스 토큰(access_token) : API 요청의 Authorization 헤더에
token_type
의 값(Bearer
)으로 전달해야 합니다. 액세스 토큰은 30분간 유효합니다. - 리프레시 토큰(refresh_token) : 슬라이딩 세션을 위해 리프레시 토큰이 함께 발급됩니다. 액세스 토큰이 만료된 경우 리프레시 토큰을 이용하여 다시 토큰을 발급받을 수 있습니다.
리프레시 토큰은 60일 간 유효합니다. 발급받은 후 30일이 지난 후 access_token 재발급시에 새로운 리프레시 토큰이 발급됩니다. 따라서 리프레시 토큰이 재발급될 때마다 리프레시 토큰을 안전한 곳에 저장해 두어야 합니다.
리프레시 토큰을 이용한 토큰 갱신
액세스 토큰은 유효 기간이 짧습니다. 액세스 토큰의 기한이 만료되었을 경우 리프레시 토큰을 이용하여 새로운 액세스 토큰을 발급받을 수 있습니다.
요청 중 grant_type
에 "refresh_token" 값을 넣어 요청해 주세요.
응답에서 refresh_token 은 요청 시 사용된 리프레시 토큰의 만료 시간이 30일 미만으로 남았을 때만 갱신되어 전달됩니다.
요청하기
curl --request POST \
--url https://api.modusign.co.kr/oauth/token \
--header 'Accept: application/json' \
--header 'Content-Type: application/json' \
--data '
{
"grant_type": "refresh_token",
"client_id": "CLIENT-ID",
"client_secret": "CLIENT-SECRET",
"refresh_token": "REFRESH-TOKEN",
}
'
const fetch = require('node-fetch');
const url = 'https://api.modusign.co.kr/oauth/token';
const options = {
method: 'POST',
headers: {Accept: 'application/json', 'Content-Type': 'application/json'},
body: JSON.stringify({
grant_type: 'refresh_token',
client_id: 'CLIENT-ID',
client_secret: 'CLIENT-SECRET',
redirect_uri: 'http://example.com',
code: '',
refresh_token: 'REFRESH-TOKEN',
})
};
fetch(url, options)
.then(res => res.json())
.then(json => console.log(json))
.catch(err => console.error('error:' + err));
토큰 삭제
보안을 위해 사용자가 연동을 해지했을 때, 토큰 발급 취소 API를 이용하여 액세스 토큰을 삭제해 주세요.
리프레시 토큰이 탈취된 경우에도 마찬가지로 리프레시 토큰을 삭제해 주세요.
요청하기
curl --request POST \
--url https://api.modusign.co.kr/oauth/token/revoke \
--header 'Content-Type: application/json' \
--data '
{
"client_id": "CLIENT-ID",
"client_secret": "CLIENT-SECRET",
"token": "TOKEN"
}
'
const fetch = require('node-fetch');
const url = 'https://api.modusign.co.kr/oauth/token/revoke';
const options = {
method: 'POST',
headers: {'Content-Type': 'application/json'},
body: JSON.stringify({client_id: 'CLIENT-ID', client_secret: 'CLIENT-SECRET', token: 'TOKEN'})
};
fetch(url, options)
.then(res => res.json())
.then(json => console.log(json))
.catch(err => console.error('error:' + err));
응답
올바르게 처리될 시 HTTP 204 응답이 돌아옵니다.
OAuth 액세스 토큰 사용하기
발급받은 액세스 토큰으로 문서 리스트 조회 API를 이용하는 예입니다.
Authorization Header에 Bearer
타입으로 발급받은 액세스 토큰 access_token
을 설정하여 유저를 대신해 리소스에 접근할 수 있습니다.
curl --request GET \
--url 'https://api.modusign.co.kr/documents?offset=0&limit=10' \
--header 'Authorization: Bearer OAUTH-TOKEN'
const fetch = require('node-fetch');
const url = 'https://api.modusign.co.kr/documents';
const options = {
method: 'GET',
headers: {Authorization: 'Bearer OAUTH-TOKEN'}
};
fetch(url, options)
.then(res => res.json())
.then(json => console.log(json))
.catch(err => console.error('error:' + err));
Updated 5 months ago