OAuth 2.0 적용하기
개요
OAuth 2.0은 사용자의 비밀번호와 같은 민감한 정보를 직접 공유하지 않고도 사용자가 허용한 범위 내에서만 서비스에 접근할 수 있게 해주는 보안 인증 방식입니다.
시작하기 전 준비사항
OAuth 2.0 인증을 구현하기 전에 반드시 완료해야 할 사항들입니다:
- 서비스 등록: 개발하신 서비스나 앱을 솔라피 앱스토어에 등록해주세요
- 클라이언트 정보 발급: 등록 완료 후 클라이언트 ID와 클라이언트 시크릿을 발급받으실 수 있습니다
클라이언트 시크릿은 최초 생성 시에만 확인 가능하므로 안전하게 보관해주세요
OAuth 2.0을 활용한 실제 개발 예제는 OAuth2를 이용한 웹 어플리케이션 제작 바로가기를 참고해주세요.
인증 흐름 개요
Step 1. 사용자 인증하기
솔라피 로그인을 호출하기 위해 아래 URL에 필요한 쿼리 파라미터를 추가하여 솔라피 계정 소유자에게 인증을 요청합니다.
/oauth2/v1/authorize
https://api.solapi.com
쿼리 파라미터
파라미터 | 타입 | 필수 | 설명 |
---|---|---|---|
client_id | string | ✅ | 앱 등록 시 발급받은 클라이언트 ID |
response_type | string | ✅ | 응답 타입 (code 또는 token ) |
redirect_uri | string | ✅ | 인증 완료 후 리다이렉트할 URL |
scope | string | ❌ | 요청할 권한 범위 (공백으로 구분) |
state | string | ❌ | CSRF 방지를 위한 임의 문자열 |
요청 예시
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'인 경우 제외)
/oauth2/v1/access_token
https://api.solapi.com
헤더
이름 | 값 | 설명 |
---|---|---|
Content-Type | application/json | 요청 본문 형식 |
요청 본문
파라미터 | 타입 | 필수 | 설명 |
---|---|---|---|
grant_type | string | ✅ | 권한 부여 타입 (authorization_code ) |
code | string | ✅ | Step 1에서 받은 인증 코드 |
client_id | string | ✅ | 클라이언트 ID |
client_secret | string | ✅ | 클라이언트 시크릿 |
redirect_uri | string | ✅ | Step 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를 호출할 수 있습니다.
/users/v1/member
https://api.solapi.com
헤더
이름 | 값 | 설명 |
---|---|---|
Authorization | Bearer {access_token} | 발급받은 액세스 토큰 |
요청 예시
GET /users/v1/member HTTP/1.1
Host: api.solapi.com
Authorization: Bearer eyGciOiNiIsIkpXVCJ9.eyJ0NTY3ODkwIiwibWRtaW4iOnRydWV9.TJVHrcEfxjoYZgeFONFh7HgQ
- 개발한 서비스나 앱을 솔라피에 등록하여 클라이언트 ID와 시크릿을 발급받습니다
- 서비스에 사용자 인증 기능을 연동합니다
- 사용자가 솔라피 계정으로 로그인합니다
- 필요한 권한에 대한 사용자 동의를 받습니다
- 인가된 권한이 포함된 액세스 토큰을 발급받습니다
- 발급받은 액세스 토큰을 Request Header에 포함하여 솔라피 API를 호출합니다
리프레시 토큰으로 액세스 토큰 재발급
액세스 토큰의 유효기간이 만료된 경우, 리프레시 토큰을 사용하여 새로운 액세스 토큰을 발급받을 수 있습니다.
/oauth2/v1/access_token
https://api.solapi.com
헤더
이름 | 값 | 설명 |
---|---|---|
Content-Type | application/json | 요청 본문 형식 |
요청 본문
파라미터 | 타입 | 필수 | 설명 |
---|---|---|---|
grant_type | string | ✅ | 권한 부여 타입 (refresh_token ) |
refresh_token | string | ✅ | 기존에 발급받은 리프레시 토큰 |
요청 예시
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 값 생성 및 사용 방법
- 생성: 인증 요청 시 고유한 임의 문자열을 생성합니다
- 저장: 생성된 값을 서버 세션이나 안전한 저장소에 보관합니다
- 전송: OAuth 인증 URL의
state
파라미터로 전송합니다 - 검증: 인증 완료 후 반환된
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
오류 발생
권한 오류 대응 방안
- 권한 확인: 토큰 발급 후 실제 부여된 권한을 확인합니다
- 기능 제한: 부족한 권한으로 인해 사용할 수 없는 기능을 비활성화합니다
- 사용자 안내: 권한 부족으로 인한 서비스 제한사항을 명확히 안내합니다
- 재인증 옵션: 필요시 추가 권한을 요청할 수 있는 재인증 기능을 제공합니다
권한 오류 처리 예시
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);
}