1. 목표
- NAVER OAuth 2.0 을 사용한 로그인 기능
2. 준비물
3. Flow
- 사용자가 OAuth 로그인을 요청한다.
- 프론트엔드에서 state를 저장하고 로그인 페이지로 리다이렉트한다.
- Autherization server에서 state와 code를 콜백받는다.
- state를 검증하고 code를 사용하여 토큰을 받는다.
- 토큰을 백엔드로 전달한다.
- 백엔드에서 토큰을 사용하여 Resource server 에 사용자 정보를 요청한다.
- 사용자 정보를 받고 사용자들 DB에 저장한다.
4. 백엔드 코드
@PostMapping("...")
public OAuthUserResponseDto OAuthLogin(@RequestHeader(value = "Authorization") String userToken) {
return userService.OAuthUser(OAuthUserToken.builder().userToken(userToken).build());
}
public OAuthUserResponseDto OAuthUser(OAuthUserToken oAuthUserToken) {
WebClient client = WebClient.create("http://localhost:8080");
OAuthUserInfoDto userInfo = client.post()
.uri(userInfoUri)
.header(HttpHeaders.AUTHORIZATION, oAuthUserToken.getUserToken())
.retrieve()
.bodyToMono(OAuthUserInfoDto.class)
.block();
if(userInfo == null) throw new ResponseStatusException(HttpStatus.FORBIDDEN, "Resource Service Error!");
String email = userInfo.getResponse().getEmail();
UsersDto usersDto = UsersDto.builder().email(email).build();
if(!usersRepository.existsByEmail(email)) {
usersDto.setPassword(email.substring(10));
usersDto.setCreatedUser();
usersRepository.save(UsersDto.toEntity(usersDto));
}
Users foundUser = usersRepository.findByEmail(email).orElseThrow(() -> new ResponseStatusException(NOT_FOUND, "존재하지 않는 사용자 입니다."));
UsersDto usersDto1 = signIn(UsersDto.of(foundUser));
return OAuthUserResponseDto.builder()
.authorization(usersDto1.getUserToken().getAccessToken())
.isAdmin(usersDto1.getIsAdmin())
.email(usersDto1.getEmail())
.build();
}