댕댕워크 프로젝트를 하며 소셜 로그인을 구현했는데 그 내용에 대해 정리한다. REST API로 개발했다.
Google, Kakao, Naver 별로 애플리케이션을 설정하는 방법을 정리해두었다.
👉 OAuth 사전 작업
OAuth provider별 로그인 요청은 다음과 같이 보낸다.
GET 요청이 아니라 해당 url로 페이지 이동을 해야함에 주의!
let url = '';
switch (provider) {
case 'google':
url = `https://accounts.google.com/o/oauth2/v2/auth?client_id=${GOOGLE_CLIENT_ID}&redirect_uri=${REDIRECT_URI}/callback&response_type=code&access_type=offline&scope=https://www.googleapis.com/auth/userinfo.email https://www.googleapis.com/auth/userinfo.profile&prompt=select_account`;
break;
case 'kakao':
url = `https://kauth.kakao.com/oauth/authorize?response_type=code&client_id=${KAKAO_CLIENT_ID}&redirect_uri=${REDIRECT_URI}/callback&prompt=select_account`;
break;
case 'naver':
url = `https://nid.naver.com/oauth2.0/authorize?response_type=code&client_id=${NAVER_CLIENT_ID}&redirect_uri=${REDIRECT_URI}/callback&state=naverLoginState&auth_type=reauthenticate`;
break;
}
window.location.href = url;
/auth/login
LogicPOST https://oauth2.googleapis.com/token
Content-type: application/x-www-form-urlencoded
{
client_id: ${CLIENT_ID},
client_secret: ${CLIENT_SECRET},
code: ${AUTHORIZE_CODE},
grant_type: ‘authorization_code’,
redirect_uri: ${REDIRECT_URI}
}
POST https://kauth.kakao.com/oauth/token
Content-type: application/x-www-form-urlencoded;charset=utf-8
{
grant_type: ‘authorization_code’,
client_id: ${CLIENT_ID},
redirect_uri: ${REDIRECT_URI},
code: ${AUTHORIZE_CODE},
client_secret: ${CLIENT_SECRET}
}
GET/POST https://nid.naver.com/oauth2.0/token?grant_type=authorization_code&client_id=${CLIENT_ID}&client_secret=${CLIENT_SECRET}&code=${AUTHORIZE_CODE}&state=${STATE}
GET https://www.googleapis.com/oauth2/v2/userinfo
Authorization: Bearer ${OAUTH_ACCESS_TOKEN}
GET https://kapi.kakao.com/v2/user/me
Authorization: Bearer ${OAUTH_ACCESS_TOKEN}
Content-type: application/x-www-form-urlencoded;charset=utf-8
GET/POST https://openapi.naver.com/v1/nid/me
Authorization: Bearer ${OAUTH_ACCESS_TOKEN}
/auth/signup
LogicoauthNickname#randomId
형태의 닉네임, email, profileImage, oauthAccessToken, oauthRefreshToken, refreshToken)OAuth Provider | Access Token 수명 | Refresh Token 수명 |
---|---|---|
1시간 | 설정된 수명 X | |
Kakao | 6시간 | 2달 (요청 시 사용된 refresh token의 남은 유효기간이 1개월 이하인 경우 access token 재발급 시 refresh token도 재발급됨) |
Naver | 1시간 | 1년 (access token 갱신 시 해당 시점으로부터 1년 연장) |
1h
: OAuth access token 최소 수명){
userId: number, // DB에 저장된 회원 id
provider: 'google' | 'kakao' | 'naver'
}
14d
){
oauthId: string, // OAuth server로부터 받은 회원 id
provider: 'google' | 'kakao' | 'naver'
}
💡 왜 refresh token에는 userId가 아니라 oauthId인가?
DB에 refresh token을 저장해야 한다. 회원가입의 경우 새로운 row를 추가해야 하는데
- refresh token에 userId를 넣으면 row를 추가한 후 생성된 userId를 가지고 refresh token을 만든 후 다시 해당 row를 업데이트해주어야 한다.
- refresh token에 oauthId를 넣으면 row를 추가할 때 함께 저장 가능하다. 즉, query가 한 번 줄어든다.
/auth/logout
Logic따로 로그아웃 api가 없다.
POST https://kapi.kakao.com/v1/user/logout
Authorization: Bearer ${OAUTH_ACCESS_TOKEN}
따로 로그아웃 api가 없다.
http://nid.naver.com/nidlogin.logout
으로 보내기auth_type=reauthenticate
query 추가)/auth/deactivate
LogicPOST https://oauth2.googleapis.com/revoke?token=${OAUTH_ACCESS_TOKEN}
Content-type: application/x-www-form-urlencoded
POST https://kapi.kakao.com/v1/user/unlink
Authorization: Bearer ${OAUTH_ACCESS_TOKEN}
GET/POST https://nid.naver.com/oauth2.0/token?grant_type=delete&client_id=${CLIENT_ID}&client_secret=${CLIENT_SECRET}&access_token=${OAUTH_ACCESS_TOKEN}&service_provider=NAVER
/auth/token
LogicPOST https://oauth2.googleapis.com/token
Content-type: application/x-www-form-urlencoded
{
client_id: ${CLIENT_ID},
client_secret: ${CLIENT_SECRET},
grant_type: ‘refresh_token’,
refresh_token: ${OAUTH_REFRESH_TOKEN}
}
POST https://kauth.kakao.com/oauth/token
Content-type: application/x-www-form-urlencoded;charset=utf-8
{
grant_type: ‘refresh_token’,
client_id: ${CLIENT_ID},
refresh_token: ${OAUTH_REFRESH_TOKEN},
client_secret: ${CLIENT_SECRET}
}
GET/POST https://nid.naver.com/oauth2.0/token?grant_type=refresh_token&client_id=${CLIENT_ID}&client_secret=${CLIENT_SECRET}&refresh_token=${OAUTH_REFRESH_TOKEN}