점프 투 스프링부트 추가 기능 구현 - 소셜 로그인 기능 구현

박철현·2023년 8월 10일
0

점프투스프링부트

목록 보기
10/14
post-thumbnail
  • 점프 투 스프링부트 추가 기능 구현 아홉번째, 소셜 로그인 기능 구현

  • 구현한 기능
    1) 카카오 로그인
    2) 구글 로그인
    3) 네이버로그인
    4) 소셜 로그인 사용자 비번 랜덤 설정 및 변경 메뉴 숨기기

  • 로그인 창

  • 마이페이지 화면

  • OAuth를 통해 Access Token 얻는 과정을 한번 다시 이해하고 접근하면 이해가 더 잘 갈 것 같습니다.

  • 혹시 그림이 잘 안들어 오시면 과정을 글로 적어둔 포스팅 참고해도 좋을 것 같습니다!
    [영상후기] WEB2-OAuth - 생활코딩님 영상

  • 처음에 등록 부분을 하고, 스프링부트 yml에 설정하고, 스프링 시큐리티, oauth-client 의존성을 받으면 중간 과정은 다 해줍니다.

    • '/oauth2/authorization/' 형태로 요청
    • OAuth2LoginAuthenticationFilter가 요청을 인터셉트하여 yml에 있는 clientId 등의 정보를 추가하여 실제 요청 전송
    • 사용자 로그인 및 권한 승인 후의 과정 자동화
      • Server로 Authorization Code 보내고 등 해서 Access Token 발행까지의 과정 자동
  • 1) oauth2 의존성 추가

implementation 'org.springframework.boot:spring-boot-starter-oauth2-client'
  • 2) SecurityConfig에 oauth2Login 설정 추가
	.oauth2Login(
				oauth2Login -> oauth2Login
					.loginPage("/user/login")
			)
  • 3) CustomOAuth2UserService && CustomOAuth2User 생성
    • 스프링 시큐리티를 DB에서 저장된 회원으로 로그인 하기 위해서 CustomUserService 만들어 User 객체를 생성하여 반환한 것 처럼 OAuthUser를 구현한 객체가 필요합니다.
    • getName() 메서드는 사용자에 대한 고유 식별자를 반환하는데, 이를 활용하여 username 설정합니다
      ex) KAKAO__
    • naver 로그인의 경우 맵 형태로 되어있어 id키값을 추출하여 넣어줍니다.
@Service
@Transactional(readOnly = true)
@RequiredArgsConstructor
@Slf4j
public class CustomOAuth2UserService extends DefaultOAuth2UserService {
	private final UserService userService;

	// 카카오톡 로그인이 성공할 때 마다 이 함수가 실행된다.
	@Override
	@Transactional
	public OAuth2User loadUser(OAuth2UserRequest userRequest) throws OAuth2AuthenticationException {
		// access 토큰으로 user 정보 조회
		OAuth2User oAuth2User = super.loadUser(userRequest);

		String providerTypeCode = userRequest.getClientRegistration().getRegistrationId().toUpperCase();

		String oauthId = switch (providerTypeCode) {
			case "NAVER" -> ((Map<String, String>) oAuth2User.getAttributes().get("response")).get("id");
			default -> oAuth2User.getName();
		};

		String username = providerTypeCode + "__%s".formatted(oauthId);

		SiteUser siteUser = userService.whenSocialLogin(providerTypeCode, username);

		return new CustomOAuth2User(siteUser.getUsername(), siteUser.getPassword(), siteUser.getGrantedAuthorities());
	}
}

class CustomOAuth2User extends User implements OAuth2User {

	public CustomOAuth2User(String username, String password, Collection<? extends GrantedAuthority> authorities) {
		super(username, password, authorities);
	}

	@Override
	public Map<String, Object> getAttributes() {
		return null;
	}

	@Override
	public String getName() {
		return getUsername();
	}
}
  • 4) UserService create 메서드 수정
    • 기존 로그인 방식 + OAuth 로그인 방식이 추가되었기에 이에 맞게 join 메서드를 생성하였습니다.
    • 서비스 메서드는 깃허브 참고!
  • 5) SiteUser 엔티티 수정
	private String email;
	private String providerTypeCode;
  • 기존 회원가입 방식이면 "SBB" 형태로 가입한 것으로 저장하고, 소셜로그인 방식이면 가입한 경로를 providerTypeCode 변수에 저장해줍니다.

  • 이메일의 경우 기존에 unique 속성이 있었는데, 이메일 속성을 소셜로그인의 경우 모두 공백으로 가입하게 설정하여 유니크 속성을 제거했습니다.

  • 6) .yml 설정 : GitHub에서 확인해주세요!

  • 상세 코드를 확인하고 싶은 분들은 Git-PR를 참조해주세요.

  • 참고자료 : 카카오 로그인 구현 및 OAuth2 동작 원리 살펴보기

profile
비슷한 어려움을 겪는 누군가에게 도움이 되길

2개의 댓글

comment-user-thumbnail
2023년 8월 10일

즐겁게 읽었습니다. 유용한 정보 감사합니다.

1개의 답글