이 글에 등장하는 전체 코드는 깃허브 저장소에서 확인할 수 있다.
사용자 로그인 진입점#
index.html
사용자가 네이버 로그인 버튼을 클릭하면, 다음과 같은 URL로 이동한다:
https://nid.naver.com/oauth2.0/authorize?
client_id={내 네이버 클라이언트 ID}response_type=coderedirect_uri={네이버 개발자센터에 등록된 내 서버 URI}
해당 화면에서 사용자는 네이버 계정으로 인증을 진행하게 된다.
리다이렉트#
인증이 성공하면, 사용자는 redirect_uri로 이동한다.
여기서 파라미터로
code가 넘어오는데, 이 코드와 토큰을 교환하게 된다. (Authorization Code Exchange)
@GetMapping("/custom/oauth2/code/naver")
fun recieveNaverCodeAnd(@RequestParam code: String)code와 네이버에서 발급받은 client_id, client_secret, grant_type, redirect_uri를 application/x‑www‑form‑urlencoded 형식으로 토큰 발급 엔드포인트에 전송한다.
참고 : redirect_uri는 로그인 요청 시 전달했던 값과 동일해야 한다는 검증용 파라미터일 뿐, 이 단계에서 실제로 리다이렉트되지는 않는다.
val form = LinkedMultiValueMap<String, String>().apply {
add("client_id", oauth2CustomProperties.naverClientId)
add("client_secret", oauth2CustomProperties.naverClientSecret)
add("code", code)
add("grant_type", "authorization_code")
add("redirect_uri", "http://localhost:8080/custom/oauth2/code/naver")
}네이버는 다음과 같이 응답한다.
{
"access_token": "AAAANauk2PFBn3CKu...",
"refresh_token": "Biqwefwef...",
"token_type": "bearer",
"expires_in": "3600"
}여기까지가 OAuth2의 인가 코드 플로우(Authorization Code Flow)에 해당한다. 응답의 access_token을 가지고 이제 네이버의 서비스를 사용할 수 있다.
부록: 네이버 사용자 정보 요청하기#
위에서 발급받은 access_token을 Bearer 인증 방식으로 헤더에 포함해 (Authorization) "https://openapi.naver.com/v1/nid/me"에 GET 요청을 보내면, 다음과 같은 네이버의 사용자 정보를 가져올 수 있다.
{
"resultcode": "00",
"message": "success",
"response": {
"id": "YES0Z444xu4u1m9t2jFySZmtS2iz5323k0LLs6nrwXQH8",
"nickname": "iamwho",
"profile_image": "https://ssl.pstatic.net/static/pwe/address/img_profile.png",
"age": "20-29",
"gender": "M",
"email": "[email protected]",
"mobile": "010-1234-5678",
"mobile_e164": "+821077777",
"name": "홍길동",
"birthday": "07-01",
"birthyear": "1997"
}
}다음 글에서는 OIDC 구현 과정을 설명하겠다.