시큐리티 OAuth (Oauth Client)를 사용할거면 redirect URL의 저 부분은 고정이다.
저기에 대한 컨트롤러 주소를 만들 필요가 없다는 뜻.
@GetMapping("/login/oauth2/code/google")
이런것을 안만들어도됨
이 주소도 Oauth Client 라이브러리를 쓰면 고정!
securityConfig에 아래 and() 부터 추가함
원래 인증이 필요한 경우 다 loginForm으로 가게 했는데
똑같이 가게 만듦
이렇게 함으로써 후처리만 하면됨.
구글 로그인이 완료된 뒤의 후처리가 필요함
일반적으론 이렇게 흘러감
구글은 바로 받아줌
@Service
public class PrincipalOauth2UserService extends DefaultOAuth2UserService {
//구글로부터 받은 userRequest 데이터에 대한 후처리되는 함수
@Override
public OAuth2User loadUser(OAuth2UserRequest userRequest) throws OAuth2AuthenticationException {
System.out.println("getClientRegistration" + userRequest.getClientRegistration());
// registration Id로 어떤 OAuth로 로그인했는지 확인 가능
System.out.println("getAccessToken : " + userRequest.getAccessToken().getTokenValue());
// 구글로그인 버튼 클릭 -> 구글 로그인 창이 뜨고 -> 구글 로그인을 진행완료 -> 코드를 리턴받음 (OAuth-Client 라이브러리가 받음)
// -> 코드를 통해서 AccessToken 을 요청 -> AccessToken 을 받음
// 여기까지가 userRequest 정보이다.
// 이 userRequest 정보로 회원 프로필을 받아야함
// 그때 사용되는 함수가 loadUser함수이다. 이 함수를 통해서 회원 프로필을 받을 수 있다.
System.out.println("getAttributes : " + super.loadUser(userRequest).getAttributes());
return super.loadUser(userRequest);
}
}
@GetMapping("/test/login")
public @ResponseBody String testLogin(Authentication authentication) {
// DI 하는 것(의존성 주입)
// 의존성주입을 하면 authentication 객체 안에 principal의 리턴 타입이 Object 이기 때문에
// 얘를 아래아래 줄처럼 받아서 getUser를 그 다음줄 처럼 호출함.
System.out.println("/test/login =================");
PrincipalDetails principalDetails = (PrincipalDetails) authentication.getPrincipal();
System.out.println("authentication" + principalDetails.getUser());
return "세션 정보 확인하기";
}
getUser한 부분
@GetMapping("/test/login")
public @ResponseBody
String testLogin(Authentication authentication, @AuthenticationPrincipal UserDetails userDetails) {
// DI 하는 것(의존성 주입)
// 의존성주입을 하면 authentication 객체 안에 principal의 리턴 타입이 Object 이기 때문에
// 얘를 아래아래 줄처럼 받아서 getUser를 그 다음줄 처럼 호출함.
System.out.println("/test/login =================");
PrincipalDetails principalDetails = (PrincipalDetails) authentication.getPrincipal();
System.out.println("authentication" + principalDetails.getUser());
//저 @AuthenticationPrincipal을 통해서 session 정보를 알 수 있다.
System.out.println("userDetails : " + userDetails.getUsername());
return "세션 정보 확인하기";
}
근데 우리가 저 어노테이션 옆에 UserDetails을 PrincipleDetails가 상속했기 때문에 이걸로 부르는 것도 가능하다.
@GetMapping("/test/login")
public @ResponseBody
String testLogin(Authentication authentication, @AuthenticationPrincipal PrincipalDetails princDetails) {
System.out.println("/test/login =================");
PrincipalDetails principalDetails = (PrincipalDetails) authentication.getPrincipal();
System.out.println("authentication" + principalDetails.getUser());
//저 @AuthenticationPrincipal을 통해서 session 정보를 알 수 있다.
System.out.println("userDetails : " + princDetails.getUsername());
return "세션 정보 확인하기";
}
OAuth는 princDetails를 사용하면 캐스팅에러가 뜸.
따라서 OAuth2User로 캐스팅해줘야함
@GetMapping("/test/oauth/login")
public @ResponseBody
String testOAuthLogin(Authentication authentication) {
System.out.println("/test/oauth/login =================");
OAuth2User oAuth2User = (OAuth2User) authentication.getPrincipal();
System.out.println("authentication" + oAuth2User.getAuthorities());
return "Oauth 세션 정보 확인하기";
}
인프런강의 시큐리티 무료강의를 수강했습니다.