[CowAPI] 27. OAuth 2.0

준돌·2022년 7월 12일
0

오늘의 Cow

목록 보기
32/45

1. 목표

  • NAVER OAuth 2.0 을 사용한 로그인 기능

2. 준비물

  • NAVER 개발자 센터에서 애플리케이션 등록

3. Flow

  1. 사용자가 OAuth 로그인을 요청한다.
  2. 프론트엔드에서 state를 저장하고 로그인 페이지로 리다이렉트한다.
  3. Autherization server에서 state와 code를 콜백받는다.
  4. state를 검증하고 code를 사용하여 토큰을 받는다.
  5. 토큰을 백엔드로 전달한다.
  6. 백엔드에서 토큰을 사용하여 Resource server 에 사용자 정보를 요청한다.
  7. 사용자 정보를 받고 사용자들 DB에 저장한다.

4. 백엔드 코드

// 1. User Controller
// 기존의 유저 컨트롤러에 API 추가

@PostMapping("...")
public OAuthUserResponseDto OAuthLogin(@RequestHeader(value = "Authorization") String userToken) {
	return userService.OAuthUser(OAuthUserToken.builder().userToken(userToken).build());
}
// 2. User Service
// 기존의 유저 서비스에 로직 추가
// WebFlux를 사용하여 webclient로 요청
// 모노 패턴을 통해 받은 사용자 정보를 동기로 처리

public OAuthUserResponseDto OAuthUser(OAuthUserToken oAuthUserToken) {
	// Resource Server 로 요청할 WebClient
	WebClient client = WebClient.create("http://localhost:8080");

	// User Info 요청 하고 받기
    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();

    // OAuth 최초 가입 사용자라면
    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();
}
profile
눈 내리는 겨울이 좋아!

0개의 댓글