본문으로 건너뛰기

OAuth 2.0 적용하기

개요

OAuth 2.0은 사용자의 비밀번호와 같은 민감한 정보를 직접 공유하지 않고도 사용자가 허용한 범위 내에서만 서비스에 접근할 수 있게 해주는 보안 인증 방식입니다.

시작하기 전 준비사항

OAuth 2.0 인증을 구현하기 전에 반드시 완료해야 할 사항들입니다:

  1. 서비스 등록: 개발하신 서비스나 앱을 솔라피 앱스토어에 등록해주세요
  2. 클라이언트 정보 발급: 등록 완료 후 클라이언트 ID와 클라이언트 시크릿을 발급받으실 수 있습니다
시크릿 보안 관리

클라이언트 시크릿은 최초 생성 시에만 확인 가능하므로 안전하게 보관해주세요

OAuth 2.0을 활용한 실제 개발 예제는 OAuth2를 이용한 웹 어플리케이션 제작 바로가기를 참고해주세요.



인증 흐름 개요

OAuth2 Flow



Step 1. 사용자 인증하기

솔라피 로그인을 호출하기 위해 아래 URL에 필요한 쿼리 파라미터를 추가하여 솔라피 계정 소유자에게 인증을 요청합니다.

GET /oauth2/v1/authorize
Base URL: https://api.solapi.com

쿼리 파라미터

파라미터타입필수설명
client_idstring앱 등록 시 발급받은 클라이언트 ID
response_typestring응답 타입 (code 또는 token)
redirect_uristring인증 완료 후 리다이렉트할 URL
scopestring요청할 권한 범위 (공백으로 구분)
statestringCSRF 방지를 위한 임의 문자열

요청 예시

GET /oauth2/v1/authorize?client_id=your_client_id&response_type=code&redirect_uri=https://yourapp.com/callback&scope=accounts:read+users:read&state=random_string_123 HTTP/1.1
Host: api.solapi.com

위 요청이 성공하면 사용자는 솔라피 인증 페이지로 이동하여 앱에 권한을 부여할 수 있습니다.


응답 형태

요청 시 설정한 response_type에 따라 응답 형태가 달라집니다:

response_type이 'code'인 경우:

{
"code": "ADFKVJCK19JDFKL2KFJLS3388",
"state": "요청 시 전송했던 state 값"
}

response_type이 'token'인 경우:

{
"access_token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.ZwUymzWAUiTxQ...",
"refresh_token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.ZwUymzWAUiTxQ..."
}

응답에 포함된 state 값을 통해 해당 요청이 어떤 사용자에 대한 요청인지 확인할 수 있습니다.



Step 2. 액세스 토큰 발급받기

사용자 인증 완료 후 발급받은 code를 사용하여 액세스 토큰을 발급받을 수 있습니다. (response_type이 'token'인 경우 제외)

POST /oauth2/v1/access_token
Base URL: https://api.solapi.com

헤더

이름설명
Content-Typeapplication/json요청 본문 형식

요청 본문

파라미터타입필수설명
grant_typestring권한 부여 타입 (authorization_code)
codestringStep 1에서 받은 인증 코드
client_idstring클라이언트 ID
client_secretstring클라이언트 시크릿
redirect_uristringStep 1에서 사용한 리다이렉트 URI

요청 예시

POST /oauth2/v1/access_token HTTP/1.1
Host: api.solapi.com
Content-Type: application/json

{
"grant_type": "authorization_code",
"code": "ADFKVJCK19JDFKL2KFJLS3388",
"client_id": "your_client_id",
"client_secret": "your_client_secret",
"redirect_uri": "https://yourapp.com/callback"
}

응답

{
"access_token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.ZwUymzWAUiTxQ...",
"refresh_token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.ZwUymzWAUiTxQ...",
"token_type": "Bearer",
"expires_in": 86400
}

토큰 유효기간 및 재발급

  • 액세스 토큰: 24시간 동안 유효
  • 리프레시 토큰: 만료기한 없음, 최초 액세스 토큰 발급 시에만 확인 가능하므로 안전하게 보관해주세요


Step 3. 액세스 토큰으로 API 접근하기

발급받은 액세스 토큰을 Authorization 헤더에 포함하여 솔라피 API를 호출할 수 있습니다.

GET /users/v1/member
Base URL: https://api.solapi.com

헤더

이름설명
AuthorizationBearer {access_token}발급받은 액세스 토큰

요청 예시

GET /users/v1/member HTTP/1.1
Host: api.solapi.com
Authorization: Bearer eyGciOiNiIsIkpXVCJ9.eyJ0NTY3ODkwIiwibWRtaW4iOnRydWV9.TJVHrcEfxjoYZgeFONFh7HgQ
OAuth 2.0 인증 프로세스 요약
  1. 개발한 서비스나 앱을 솔라피에 등록하여 클라이언트 ID와 시크릿을 발급받습니다
  2. 서비스에 사용자 인증 기능을 연동합니다
  3. 사용자가 솔라피 계정으로 로그인합니다
  4. 필요한 권한에 대한 사용자 동의를 받습니다
  5. 인가된 권한이 포함된 액세스 토큰을 발급받습니다
  6. 발급받은 액세스 토큰을 Request Header에 포함하여 솔라피 API를 호출합니다


리프레시 토큰으로 액세스 토큰 재발급

액세스 토큰의 유효기간이 만료된 경우, 리프레시 토큰을 사용하여 새로운 액세스 토큰을 발급받을 수 있습니다.

POST /oauth2/v1/access_token
Base URL: https://api.solapi.com

헤더

이름설명
Content-Typeapplication/json요청 본문 형식

요청 본문

파라미터타입필수설명
grant_typestring권한 부여 타입 (refresh_token)
refresh_tokenstring기존에 발급받은 리프레시 토큰

요청 예시

POST /oauth2/v1/access_token HTTP/1.1
Host: api.solapi.com
Content-Type: application/json

{
"grant_type": "refresh_token",
"refresh_token": "eyGciOiNiIsIkpXVCJ9.eyJ0NTYDkwIwibWaW4iOnRydWV9.TVEfxjoYZgeFONFh7HgQ"
}

응답

{
"access_token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.NewAccessToken...",
"token_type": "Bearer",
"expires_in": 86400
}


State 파라미터 활용 가이드

State란 무엇인가요?

state 파라미터는 OAuth 2.0 인증 과정에서 보안을 강화하기 위해 사용되는 값입니다. 주요 목적은 다음과 같습니다:

  • CSRF 공격 방지: Cross-Site Request Forgery 공격을 차단합니다
  • 요청 검증: 인증 요청과 응답이 동일한 세션에서 발생했는지 확인합니다

State 값 생성 및 사용 방법

  1. 생성: 인증 요청 시 고유한 임의 문자열을 생성합니다
  2. 저장: 생성된 값을 서버 세션이나 안전한 저장소에 보관합니다
  3. 전송: OAuth 인증 URL의 state 파라미터로 전송합니다
  4. 검증: 인증 완료 후 반환된 state 값이 원래 값과 일치하는지 확인합니다

State 값 예시

// 1. 인증 요청 시 state 생성
const state = crypto.randomBytes(16).toString('hex'); // 예: "a1b2c3d4e5f6..."
sessionStorage.setItem('oauth_state', state);

// 2. OAuth URL에 state 포함
const authUrl = `https://api.solapi.com/oauth2/v1/authorize?response_type=code&client_id=${CLIENT_ID}&state=${state}`;

// 3. 콜백에서 state 검증
const returnedState = req.query.state;
const originalState = sessionStorage.getItem('oauth_state');

if (returnedState !== originalState) {
throw new Error('State 값이 일치하지 않습니다. CSRF 공격 가능성이 있습니다.');
}


권한(Scope) 오류 처리

권한 불일치 문제

애플리케이션에서 요구하는 권한과 사용자가 실제로 승인한 권한이 다를 경우 API 호출 시 오류가 발생할 수 있습니다.

예시 상황:

  • 애플리케이션 요구 권한: accounts:read users:read
  • 사용자 승인 권한: accounts:read
  • 결과: users:read 관련 API 호출 시 Unauthorized 오류 발생

권한 오류 대응 방안

  1. 권한 확인: 토큰 발급 후 실제 부여된 권한을 확인합니다
  2. 기능 제한: 부족한 권한으로 인해 사용할 수 없는 기능을 비활성화합니다
  3. 사용자 안내: 권한 부족으로 인한 서비스 제한사항을 명확히 안내합니다
  4. 재인증 옵션: 필요시 추가 권한을 요청할 수 있는 재인증 기능을 제공합니다

권한 오류 처리 예시

try {
const response = await fetch('https://api.solapi.com/users/v1/member', {
headers: {
'Authorization': `Bearer ${accessToken}`
}
});

if (response.status === 401) {
// 권한 부족 오류 처리
showMessage('사용자 정보 조회 권한이 없습니다. 서비스 이용에 제한이 있을 수 있습니다.');
disableUserFeatures();
}
} catch (error) {
console.error('API 호출 오류:', error);
}