일반적으로 클라이언트에서 회원가입 로그인을 시도하게되면 서버에서는 코드(인증)와 액세스 토큰(권한)을 받고 사용자 프로필 정보를 가져와 그 정보를 토대로 회원가입을 자동으로 진행시키기도 한다.
그러나 구글로그인의 경우 코드를 받는게 아닌 액세스토큰과 사용자 프로필 정보를 함께 받게 되는데 이것이 oauth클라이언트 라이브러리의 장점이다.
먼저 SecurityConfig 에서 SecurityFilterChain에서 OAuth2 클라이언트 라이브러리를 build해주도록 하자.
SecurityConfig
@Configuration
@EnableWebSecurity // 스프링 시큐리티 필터가 스프링 필터 체인에 등록됨
@EnableGlobalMethodSecurity(securedEnabled = true, prePostEnabled = true) //secured 어노테이션 활성화, preAuthorize 어노테이션 활성화
public class SecurityConfig {
@Autowired
private PrincipalOauth2UserService principalOauth2UserService;
@Bean
public SecurityFilterChain filter(HttpSecurity http) throws Exception {
http.csrf().disable()
.authorizeRequests()
.antMatchers("/user/**").authenticated()
.antMatchers("/manager/**").access("hasRole('ROLE_MANAGER') or hasRole('ROLE_ADMIN')") //hasRole 은 풀네임을 써줘야 하지만, hasAuthority는 앞에 ROLE_ 이 붙기 때문에
.antMatchers("/admin/**").access("hasRole('ROLE_ADMIN')")// hasRole("ROLE_ADMIN") == hasAuthority("ADMIN") 이다.
.anyRequest().permitAll()// 권한 설정, 해당페이지(antMatchers) 설정한 곳은 권한(hasAuthority)이 있어야 들어갈 수 있다.
.and()
.formLogin() //formLogin 형태
.loginPage("/loginForm") //loginpage를 낚아챔
.loginProcessingUrl("/login") // 시큐리티가 /login주소를 대신 낚아채주기 때문에 컨트롤러에 /login을 만들지 않아도됨
.defaultSuccessUrl("/")// 로그인 이후에 이동할 페이지
.and()
///////////////////////OAuth 라이브러리/////////////////////////////
.oauth2Login()
.loginPage("/loginForm") // 구글 로그인이 완료된 이후 후처리가 필요하다.
.userInfoEndpoint()
.userService(principalOauth2UserService)
;
return http.build();
}
}
여기서 userService부분은 PrincipalOauth2UserService라는 클래스를 만들어 @Service로 IoC에 등록한 후 DefalutOAuth2UserService를 extends 하여 loadUser를 오버라이드한 service이다.
이 PrincipalOauth2UserService역할은 액세스 토큰과 유저의 정보를 가져오는 역할을 할 수 있다.
어떻게 가져오는지 직접 콘솔에 찍어보도록 하자
PrincipalOauth2UserService
@Service
public class PrincipalOauth2UserService extends DefaultOAuth2UserService{
// 구글로 부터 받은 userRequest 데이터에 대한 후처리 되는 함수
@Override
public OAuth2User loadUser(OAuth2UserRequest userRequest) throws OAuth2AuthenticationException {
System.out.println("userRequest: " + userRequest);
System.out.println("getAccessToken: " + userRequest.getAccessToken());
System.out.println("getAccessTokenValue: " + userRequest.getAccessToken().getTokenValue()); // 액세스 토큰
System.out.println("getClientRegistration: " + userRequest.getClientRegistration()); // registrationId로 어떤 OAuth로 로그인 했는지 확인 가능
System.out.println("getAttributes: " + super.loadUser(userRequest).getAttributes());
return super.loadUser(userRequest);
}
}
oauth 패키지를 따로 만들어 클래스를 새로 생성해준 후 DefaultOAuth2UserService를 extends해줬다. 구글로 부터 받은 user정보들을 알 수 있는데 위처럼 알고싶은 정보들을 나열한 후 구글 로그인을 시도하면 아래와 같이 콘솔에 나오게 된다.
액세스 토큰을 활용하거나 필요한 정보가 있다면 여기서 받아오면 된다.
지금 필요한 정보는 getAttributes 부분인데 이전에 만들어둔 User에 강제로 getAttributes 내용을 넣어줄 예정이다.
이렇게 하는 이유는 일반로그인과 구글로그인이 있는데 구글 로그인을 했을 경우에도 db에 일반 로그인을 한 것과 같이 user정보들을 가져와 관리해야 하기 때문이다.
getAttributes 부분을 따로 가져와보면 아래와 같이 정보가 나열되어 있다.
getAttributes를 해본 내용
getAttributes:
{sub=100194700249082101266,
name= 박도치,
given_name=도치,
family_name=박,
picture=https://lh3.googleusercontent.com/a/AAcHTtcnXazbXZRndB6uSKzQI3sqv1c4iTP2sPM3JkHa=s96-c,
email=skfk04304@gmail.com,
email_verified=true,
locale=ko}
User 클래스
@Entity
@Data
public class User {
@Id //PrimaryKey
@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; //java.sql import
}
그렇다면 가져온 저 구글프로필을 토대로 User정보에 넣어줘야 하는데 이런식으로 넣어줄 예정이다.
username = "google_100194700249082101266"
password = "암호화('서버가 정해둔 암호')"
email = "skfk04304@gmail.com"
role = "ROLE_USER"
provider = "google"
providerId = "100194700249082101266"
정리하자면 구글로그인 버튼을 클릭했을 때 구글 로그인이 진행되고, 로그인이 완료되면 code를 return(OAuthClient 라이브러리)해주고 AccessToken요청을 하게된다. 여기까지가 userRequest정보이고 이 정보를 통해 loadUser함수가 호출되면서 구글로부터 회원 프로필을 받게 된다.
'Spring Boot' 카테고리의 다른 글
Spring boot 구글로그인 및 자동 회원가입 마무리 (0) | 2023.06.08 |
---|---|
Spring Boot OAuth 구글 로그인 (0) | 2023.06.07 |
Spring Boot Security 권한 정리 (authorizeRequests, secured, preAuthorize) (0) | 2023.06.05 |
Spring Boot Security 로그인 (0) | 2023.06.05 |
Spring Boot Security 회원가입 Form (0) | 2023.06.02 |