이전글을 읽지않으면 이해가 되지 않을 수 있습니다.
1. https://developers.naver.com/apps/#/register 접속
2. 애플리케이션 이름 : 자신이 원하는 애플리케이션 이름으로 설정
3. 사용 API : 네이버 로그인 선택, 권한은 필요한 것을 선택
4. 서비스 URL : 자신의 애플리케이션의 도메인
5. Callback (Redirect) URL : 네아로 수행과정 내에서, Redirect 되는 URL (애플리케이션 측이 구현해줘야 함)
1. Resource Owner 가 로그인 버튼을 클릭하여, 로그인을 할 수 있는 URL 을 Resource Owner 에게 제공해야한다.
Redirect URL 은 RequestParameter 로써, 아래의 4개의 정보를 필요로 한다.
- response_type : code (Authorization Code 를 의미하는 듯 하다.)
- client_id : 발급받은 Client ID
- redirect_uri : 등록한 Callback (Redirect) Url 을 "URL 인코딩 한 값"
- state : 랜덤한 값을 내가 직접 생성한다.
- response_type = code
- client_id = YqOe9i6OZ3OpWvVRVPJZ
- 발급받은 Client ID
- state = 1234
- 현재는 아무값이나 해도 됨
- redirect_uri = http%3A%2F%2Flocalhost%3A8080%2Foauth%2Fredirect_url
- 위에서 등록시 사용한 http://localhost:8080/oauth/redirect_url 을 인코딩 한 값
ex) https://nid.naver.com/oauth2.0/authorize?response_type=code&client_id=YqOe9i6OZ3OpWvVRVPJZ&redirect_uri=http%3A%2F%2Flocalhost%3A8080%2Foauth%2Fredirect_url&state=1234
해당 URL 을 직접 주소창에 붙여넣으면, 네이버 로그인 화면이 보인다.
1. 유저가 해당 화면에서 로그인한다.
2. 네이버측에서는 3xx Response + Location 헤더를 반환한다.
- Location 헤더의 값은 callback(redirect URL) 이다.
3. 유저는 callback(redirect) URL 을 호출한다.
등록과정에의 redirect_url : localhost:8080/oauth/redirect_url
주의 : 스펙에는
- http://콜백URL/redirect?code=... 이지만, redirect 부분이 없어야 동작한다.
- http://콜백URL?code=... 으로 사용하도록 한다.
성공 시 : http://[redirect_url]?code=[code값]&state=[state값] 에 대한 컨트롤러를 구현하자
@Configuration
class RestTemplateConfig {
@Bean
fun restTemplate() : RestTemplate {
return RestTemplate()
}
}
@RestController
class OAuthController(val restTemplate: RestTemplate) {
private val log = LoggerFactory.getLogger(OAuthController::class.java)
@GetMapping("/oauth/redirect_url")
fun redirectUriProcessor(@RequestParam code: String,
@RequestParam state: String) {
log.info(code) // Authorization Code 값
log.info(state) // 내가 임의로 만든 state 값
}
}
아래의 스펙을 봤을 때, 토큰을 발급하려면 아래의 파라미터가 필수적이다.
- grant_type
- client_id
- client_secret
- code
- state
발급이므로, grant_type = authorization_code 로 한다.
@RestController
class OAuthController(val restTemplate: RestTemplate) {
private val log = LoggerFactory.getLogger(OAuthController::class.java)
private val store = HashMap<String, User>()
@GetMapping("/oauth/redirect_url")
fun redirectUriProcessor(@RequestParam code: String,
@RequestParam state: String) {
log.info(code)
log.info(state)
// access_token, refresh_token 얻기
val grantType = "grant_type=authorization_code"
val clientId = "client_id=YqOe9i6OZ3OpWvVRVPJZ"
val clientSecret = "client_secret=client_secret 입력하세용"
val url = "https://nid.naver.com/oauth2.0/token" +
"?$grantType" +
"&$clientId" +
"&$clientSecret" +
"&code=$code" +
"&state=$state"
val body = restTemplate.getForEntity(url, String::class.java).body
log.info(body) --> access, refresh 토큰 값이 들어있다.
}
}
curl 을 이용해서 한번 정보를 획득해보자
curl -XGET "https://openapi.naver.com/v1/nid/me" \
-H "Authorization: Bearer [위의 코드에서 받아온 access_token 값]"
현재 코드는 callback URL 에서 access_token, refresh_token 을 가져오는 부분만 구현되어있다.
추후 아래의 구현을 하면 좋을 것 같다.
- state 값 검증
- 프로필 값 가져오기
- 캐시 or DB 에 토큰값 저장
- access_token 만료시에는 refresh_token 을 이용하여 access_token 획득