@Data
public class PrincipalDetails implements UserDetails, OAuth2User {
private User user; //해당 user의 권한을 리턴하는 곳!!
private Map<String, Object> attribute; //OAuth2 인증 시 사용자의 속성 정보를 저장하기 위해 선언된 필드
// 일반 로그인 때 사용하는 생성자
public PrincipalDetails(User user){
this.user = user;
}
//OAuth를 사용하여 로그인하는 생성자
public PrincipalDetails(User user, Map<String, Object> attribute){
this.user = user;
this.attribute = attribute;
}
@Override
public Collection<? extends GrantedAuthority> getAuthorities() {
Collection<GrantedAuthority> collection = new ArrayList<>();
collection.add((GrantedAuthority) () -> user.getRole());
return collection;
}
@Override
public String getPassword() {
return user.getPassword();
}
@Override
public String getUsername() {
return user.getUsername();
}
@Override
public boolean isAccountNonExpired() {
return true;
}
@Override
public boolean isAccountNonLocked() {
return true;
}
@Override
public boolean isCredentialsNonExpired() {
return false;
}
@Override
public boolean isEnabled() {
return true;
}
@Override
public String getName() {
return null;
}
@Override
public Map<String, Object> getAttributes() {
return attribute;
}
}
PrincipalDetails 클래스
- 지난번의 코드와는 다르게 클래스는 일반적인 사용자 정보 및 OAuth2 인증을 모두 다루기 위해 두 가지 인터페이스를 동시에 구현하였다.
- 일반적인 사용자 정보: UserDetails 인터페이스를 구현하여 일반적인 사용자 정보를 표현합니다. 이 인터페이스는 Spring Security의 인증 및 권한 부여 프로세스에 필요한 사용자 정보를 정의하는 데 사용됩니다. 이러한 정보에는 사용자 이름, 비밀번호, 권한 목록 및 기타 인증과 관련된 정보가 포함됩니다.
- OAuth2 인증 정보: OAuth2User 인터페이스를 구현하여 OAuth2 기반의 인증 정보를 나타냅니다. OAuth2 인증은 외부 인증 공급자(예: 구글, 페이스북)를 통해 사용자가 로그인하는 경우에 사용됩니다.

@Service
public class PrincipalOauth2UserService extends DefaultOAuth2UserService {
BCryptPasswordEncoder bCryptPasswordEncoder = new BCryptPasswordEncoder();
@Autowired
private UserRepository userRepository;
private static final Logger log = LoggerFactory.getLogger(PrincipalOauth2UserService.class);
//구글로부터 받은 userRequest 데이터에 대한 후처리되는 함수
//OAuth2 로그인 요청을 처리하고, OAuth2 공급자(예: 구글)에서 사용자 정보를 가져오는 역할을 수행하는 함수이다.
// 함수 종료시 @AuthenticationPrincipal 어노테이션이 만들어진다.
@Override
public OAuth2User loadUser(OAuth2UserRequest userRequest) throws OAuth2AuthenticationException{
log.info("getClientRegistration : "+userRequest.getClientRegistration());
log.info("getAccessToken : "+userRequest.getAccessToken().getTokenValue());
// DefaultOAuth2UserService를 통해 사용자 정보를 로드하고 OAuth2User 객체를 반환
OAuth2User oAuth2User = super.loadUser(userRequest);
// 구글로그인 버튼 클릭 -> 구글 로그인창 -> 로그인을 완료 -> code 리턴(OAuth-Client 라이브러리가 code를 받아줌) -> AccessToken 요청
// userRequest 정보 -> loadUser 함수 호출 -> 구글로부터 회원프로필 받아줌.
log.info("getAttributes : "+oAuth2User.getAttributes());
String provider = userRequest.getClientRegistration().getClientId();
String providerId = oAuth2User.getAttribute("sub");
String username = provider + "_" + providerId;
String password = bCryptPasswordEncoder.encode("TemporaryPasswordKey");
String email = oAuth2User.getAttribute("email");
String role = "ROLE_USER";
User userentity = userRepository.findByUsername(username);
if(userentity == null) {
userentity = User.builder()
.username(username)
.password(password)
.email(email)
.role(role)
.provider(provider)
.providerId(providerId)
.build();
userRepository.save(userentity);
}
return new PrincipalDetails(userentity, oAuth2User.getAttributes());
}
}
PrincipalOauth2UserService 클래스
- OAuth2 인증을 처리하고 외부 OAuth2 공급자(ex: 구글)로부터 사용자 정보를 가져오는 데 사용된다.
- @AuthenticationPrincipal 어노테이션은 Spring Security에서 사용되며, 현재 인증된 사용자의 Principal(주체, 즉 현재 로그인한 사용자) 객체를 가져올 때 사용
- 구글에서 받아온 사용자 정보를 가져와서 우리 프로젝트의 db에 저장하여 관리하도록 하는 코드이다.
<< 간단 코드 설명 >>
oAuth2User.getAttribute("sub"), oAuth2User.getAttribute("email");
여기서 (" ") 안에 있는 것들이 무엇인가??
바로 아래에 있는 oauth에서 받아온 유저 정보의 필드명 중에 sub와 email이라는 것을 가져와 저장하기 위해서 저렇게 코드를 작성한 것이다.
getAttributes : {sub=[어떤 데이터], name=[어떤 데이터], given_name=[어떤 데이터], family_name=[어떤 데이터], picture=[어떤 데이터], email=[어떤 데이터], email_verified=true, locale=ko}

'개발공부 > spring security & JWT 강의' 카테고리의 다른 글
[11강] 네이버 로그인 완료 (0) | 2023.11.14 |
---|---|
[10강] 페이스북 로그인 완료 (0) | 2023.11.13 |
[8강] Authentication 객체가 가질 수 있는 2가지 타입 (0) | 2023.09.24 |
[7강] 구글 회원 프로필 정보 받아보기 (0) | 2023.09.23 |
[6강] 구글 로그인 준비 (0) | 2023.09.22 |