Spring Security

[OAuth] 구글 회원 프로필 정보 받아보기

ewok 2023. 3. 26. 15:03

SecurityConfig

            .and()
            .oauth2Login()
            .loginPage("/loginForm")
            .userInfoEndpoint()
            .userService(null);	// 매개변수는 OAuth2UserService 타입인데, 아직 안만들었으니 우선 null로 한다.

    return http.build();
}

생성

package com.cos.security.config.oauth;

import org.springframework.security.oauth2.client.userinfo.DefaultOAuth2UserService;
import org.springframework.stereotype.Service;

@Service
public class PrincipalOauth2UserService extends DefaultOAuth2UserService {
}

 

SecurityConfig

@RequiredArgsConstructor
@Configuration // IoC 빈(bean)을 등록
@EnableMethodSecurity(securedEnabled = true, prePostEnabled = true)    // secured 어노테이션 활성화, preAuthorize 어노테이션 활성화
public class SecurityConfig {

    private final PrincipalOauth2UserService principalOauth2UserService;
    
    ...
    
    
    @Bean
    public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
    
    ...
    
                .and()
                .oauth2Login()
                .loginPage("/loginForm")
                .userInfoEndpoint()
                .userService(principalOauth2UserService);

        return http.build();
    }
}

 

PrincipalOauth2UserService

@Service
public class PrincipalOauth2UserService extends DefaultOAuth2UserService {

    // 로그인 후처리
    @Override
    public OAuth2User loadUser(OAuth2UserRequest userRequest) throws OAuth2AuthenticationException {
        System.out.println("userRequest : " + userRequest);
        return super.loadUser(userRequest);
    }
}

 

로그아웃 후 다시 /user로 가서 다시 로그인해보면 콘솔에 아래와 같이 나온다.

loadUser()는 구글로부터 받은 userRequest 데이터에 대한 후처리가 되는 함수이다.

 

userRequest에 어떤 정보가 들어오는지 확인해 보자

@Override
public OAuth2User loadUser(OAuth2UserRequest userRequest) throws OAuth2AuthenticationException {
    System.out.println("userRequest : " + userRequest.getClientRegistration());
    System.out.println("userRequest : " + userRequest.getAccessToken());
    System.out.println("getAttribute : " + super.loadUser(userRequest).getAttributes());
    return super.loadUser(userRequest);
}

getAttribute : {sub=숫자 21개, name=OOO(family_name + given_name 형식), given_name=OO, family_name=O, picture=https://lh3.googleusercontent.com/a/주소, email=이메일@gmail.com, email_verified=true, locale=ko}

 

이 정보를 가지고 회원가입을 아래와 같은 형식으로 할 것이다.

 

username = google_sub

password = "암호화"

email = "email 그대로"

role = "ROLE_USER"

 

사용자는 구글로 로그인할 것이기 때문에 사실 password는 null만 아니면 괜찮다.

 

그런데 이렇게 하면 일반적인 사용자인지 OAuth를 통해 로그인 한 사용자인지 구분할 수 없기 때문에 구분할 속성을 추가한다.

 

User

@Data
@Entity
public class User {
    @Id // primary key
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private int id;
    private String username;
    private String password;
    private String email;
    private String role; //ROLE_USER, ROLE_ADMIN

    private String provider;
    private String providerId;

    @CreationTimestamp
    private Timestamp createDate;
}

provider = "google"

providerId = sub

 

최종적으로

 

username = google_sub

password = "암호화"

email = "email 그대로"

role = "ROLE_USER"

provider = "google"

providerId = sub

 

이렇게 강제 회원가입을 시킬 것이다.