창업동아리에서 개발도중인 이커머스 플랫폼의 OAuth2를 이용한 소셜로그인 기능을 얼추 완성시켰다. 배운 것들을 까먹기 전에 빠르게 적어보도록하자.
UserDetails 인터페이스는 Spring Security 프레임워크에서 사용자의 인증 및 권한 부여를 관리하기 위해 사용되는 핵심 인터페이스다.
이 인터페이스는 애플리케이션에서 사용자에 대한 정보를 캡슐화하여, Sprint Security가 인증 및 권한 부여를 처리할 수 있도록 도와준다.
'UserDetails' 인터페이스는 사용자의 로그인 정보와 권한을 제공하는 객체를 정의할 때 사용된다. 특히, 사용자 인증을 위해 Sprint Security가 사용자의 세부 정보를 조회할 때 이 인터페이스를 구현한 클래스를 사용한다.
예시는 다음 'OAuth2User' 인터페이스 설명 후 같이 보이도록 하겠다.
'OAuth2User' 인터페이스는 Sprint Security의 OAuth 2.0 및 OpenID Connect(OIDC) 인증 기능을 지원하기 위해 사용되는 인터페이스이다.
인증된 사용자의 정보를 표현하며, OAuth 2.0 프로토콜을 통해 사용자 정보를 가져올 때 사용된다.
'OAuth2User' 인터페이스는 OAuth 2.0 또는 OIDC를 사용하여 외부 인증 제공자(예: Google, Facebook, GitHub 등)로부터 사용자 인증을 처리할 때 사용된다.
예를 들어, 사용자가 Google 계정으로 로그인할 때, Spring Security는 Google에서 받은 사용자 정보를 OAuth2User로 표현한다.
@RequiredArgsConstructor
public class CustomOauth2UserDetails implements UserDetails, OAuth2User {
private final Member member;// 로그인 한 멤버
private Map<String, Object> attributes; //
public CustomOauth2UserDetails(Member member, Map<String, Object> attributes) {
this.member = member;
this.attributes = attributes;
}
@Override
public Map<String, Object> getAttributes() {
return attributes;
}
@Override
public String getName() {
return null;
}
// 주어진 권한: 구글에서 이 사람에게 어떤 권한을 줬는지
@Override
public Collection<? extends GrantedAuthority> getAuthorities() {
Collection<GrantedAuthority> collection = new ArrayList<>();
collection.add(new GrantedAuthority() {
@Override
public String getAuthority() {
return member.getRole().name();
}
});
return collection;
}
@Override
public String getPassword() {
return member.getPassword();
}
@Override
public String getUsername() {
return member.getLoginId();
}
@Override
public boolean isAccountNonExpired() {
return true;
}
@Override
public boolean isAccountNonLocked() {
return true;
}
@Override
public boolean isCredentialsNonExpired() {
return true;
}
@Override
public boolean isEnabled() {
return true;
}
}
@RequiredArgsConstructor
public class CustomOauth2UserDetails implements UserDetails, OAuth2User {
private final Member member; // 로그인 한 멤버
private Map<String, Object> attributes; // OAuth 2.0 제공자로부터 받은 사용자 속성들
}
@RequiredArgsConstructor: fianl 필드에 대해 생성자를 자동으로 생성한다.
Member: 사용자의 정보를 담고있는 도메인 객체
Map<String , Object> attributes : OAuth 2.0 인증 제공자로부터 받은 사용자 속성을 저장한다. 예를 들어, Google 에서 받은 사용자 프로필 정보를 저장하는데 사용된다.
@Override
public Map<String, Object> getAttributes() {
return attributes;
}
@Override
public String getName() {
return null;
}
getAttributes(): OAuth 2.0 제공자로부터 받은 사용자 정보를 반환합니다.
getName(): OAuth 2.0에서 사용자 이름 또는 ID를 반환해야 하지만, 이 코드에서는 null을 반환하도록 되어 있다. 이 부분은 보통 사용자 식별자를 반환하도록 수정해야 합니다. -> 유저의 이름이 attribute에 포함되기 때문에 반환하지 않았다.
@Override
public Collection<? extends GrantedAuthority> getAuthorities() {
Collection<GrantedAuthority> collection = new ArrayList<>();
collection.add(new GrantedAuthority() {
@Override
public String getAuthority() {
return member.getRole().name();
}
});
return collection;
}
@Override
public String getPassword() {
return member.getPassword();
}
@Override
public String getUsername() {
return member.getLoginId();
}
@Override
public boolean isAccountNonExpired() {
return true;
}
@Override
public boolean isAccountNonLocked() {
return true;
}
@Override
public boolean isCredentialsNonExpired() {
return true;
}
@Override
public boolean isEnabled() {
return true;
}
getAuthorities(): 사용자의 권한을 반환합니다. 이 코드는 member 객체에 저장된 역할(Role)을 GrantedAuthority 객체로 변환하여 반환합니다.
getPassword(): 사용자의 비밀번호를 반환.
getUsername(): 사용자의 로그인 ID를 반환.
isAccountNonExpired(), isAccountNonLocked(), isCredentialsNonExpired(), isEnabled(): 계정 상태를 반환. 이 예제에서는 모두 true를 반환하여 계정이 활성화되어 있음을 나타낸다.
이 클래스는 Spring Security에서 사용자의 인증 정보를 나타내기 위해 UserDetails와 OAuth2User 인터페이스를 구현하고,
Member 객체는 사용자 정보를 캡슐화하고 있으며, OAuth 2.0 제공자로부터 받은 속성 정보는 attributes 맵에 저장한다.
Spring Security는 이 클래스를 사용하여 사용자 인증 및 권한 부여를 처리하며, 사용자의 계정 상태를 확인하고, OAuth 2.0 인증된 사용자 정보를 관리한다.
오늘은 Authorization Server에서 받아올 정보를 입력받고, 해당 입력에 맞는 Resource Owner를 매핑하기 위한 클래스를 만들기 위해 interface 두개를 구현해보았다. 몇일 째 처음보는 로그인 관련 기능들이지만 하다보니 흐름이 이해가 되고 있어 다행이라고 생각된다. 앞으로 얼마남지 않은 방학을 모각소로 잘 사용해보도록 하겠다.