Spring Boot + Security로 Oauth 공부하기
package com.example.oauth.domain.auth.service;
import com.example.oauth.domain.auth.presentation.dto.response.CustomOAuth2User;
import com.example.oauth.domain.auth.presentation.dto.response.OAuth2Response;
import com.example.oauth.domain.auth.presentation.dto.response.google.GoogleResponse;
import org.springframework.security.oauth2.client.userinfo.DefaultOAuth2UserService;
import org.springframework.security.oauth2.client.userinfo.OAuth2UserRequest;
import org.springframework.security.oauth2.core.OAuth2AuthenticationException;
import org.springframework.security.oauth2.core.user.OAuth2User;
import org.springframework.stereotype.Service;
@Service
public class CustomOauth2UserService extends DefaultOAuth2UserService {
@Override
public OAuth2User loadUser(OAuth2UserRequest request) throws OAuth2AuthenticationException {
OAuth2User oAuth2User = super.loadUser(request);
System.out.println("oAuth2User = " + oAuth2User.getAttributes());
String registrationId = request.getClientRegistration().getRegistrationId();
OAuth2Response oAuth2Response = null;
if(registrationId.equals("google")) {
oAuth2Response = new GoogleResponse(oAuth2User.getAttributes());
}
String role = "ROLE_USER"; // 나중에 role 설정
return new CustomOAuth2User(oAuth2Response, role);
}
}
package com.example.oauth.domain.auth.presentation.dto.response;
import lombok.RequiredArgsConstructor;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.oauth2.core.user.OAuth2User;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Map;
@RequiredArgsConstructor
public class CustomOAuth2User implements OAuth2User {
private final OAuth2Response oAuth2Response;
private final String role;
@Override
public Map<String, Object> getAttributes() {
return null;
}
@Override
public Collection<? extends GrantedAuthority> getAuthorities() {
Collection<GrantedAuthority> collection = new ArrayList<>();
collection.add(new GrantedAuthority() {
@Override
public String getAuthority() {
return role;
}
});
return collection;
}
@Override
public String getName() {
return oAuth2Response.getName();
}
public String getUserName() {
return oAuth2Response.getProvider() + " " + oAuth2Response.getProviderId();
}
}
생성자 방식으로 OAuth2Response
를 주입받는다
@Override
public Map<String, Object> getAttributes() {
return null;
}
getAttributes()
는 google, kakao 종류에 따라 키값이 다르기 때문에 나중에 구현하겠다
@Override
public Collection<? extends GrantedAuthority> getAuthorities() {
Collection<GrantedAuthority> collection = new ArrayList<>();
collection.add(new GrantedAuthority() {
@Override
public String getAuthority() {
return role;
}
});
return collection;
}
Collection을 만들고 만든 Collection에 GrantedAuthority를 생성하여 입력받은 필드의 role값을 넣어준다
@Override
public String getName() {
return oAuth2Response.getName();
}
응답받은 oAuth2Response Dto에서 getName()
을 이용하여 사용자 이름(닉네임) 을 가져온다
public String getUserName() {
return oAuth2Response.getProvider() + " " + oAuth2Response.getProviderId();
}
oAuthResponse에서 provider 값을 꺼내고 providerId와 같이 id 값으로 사용한다
package com.example.oauth.domain.user;
import jakarta.persistence.*;
import lombok.*;
@Entity(name = "user")
@Table
@Getter
@ToString
@NoArgsConstructor(access = AccessLevel.PROTECTED)
public class User {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
private String userName;
@Setter
private String email;
private String role;
@Builder
public User(Long id, String userName, String email, String role) {
this.id = id;
this.userName = userName;
this.email = email;
this.role = role;
}
}
package com.example.oauth.domain.auth.service;
import com.example.oauth.domain.auth.presentation.dto.response.CustomOAuth2User;
import com.example.oauth.domain.auth.presentation.dto.response.OAuth2Response;
import com.example.oauth.domain.auth.presentation.dto.response.google.GoogleResponse;
import com.example.oauth.domain.user.User;
import com.example.oauth.domain.user.repository.UserRepository;
import lombok.RequiredArgsConstructor;
import org.springframework.security.oauth2.client.userinfo.DefaultOAuth2UserService;
import org.springframework.security.oauth2.client.userinfo.OAuth2UserRequest;
import org.springframework.security.oauth2.core.OAuth2AuthenticationException;
import org.springframework.security.oauth2.core.user.OAuth2User;
import org.springframework.stereotype.Service;
@Service
@RequiredArgsConstructor
public class CustomOauth2UserService extends DefaultOAuth2UserService {
private final UserRepository userRepository;
@Override
public OAuth2User loadUser(OAuth2UserRequest userRequest) throws OAuth2AuthenticationException {
OAuth2User oAuth2User = super.loadUser(userRequest);
System.out.println("oAuth2User = " + oAuth2User.getAttributes());
String registrationId = userRequest.getClientRegistration().getRegistrationId();
OAuth2Response oAuth2Response = null;
if (registrationId.equals("google")) {
oAuth2Response = new GoogleResponse(oAuth2User.getAttributes());
}
// DB 저장
String userName = oAuth2Response.getProvider() + " " + oAuth2Response.getProviderId();
User userData = userRepository.findByUserName(userName);
String role = null;
if (userData == null) {
User user = User.builder()
.userName(userName)
.email(oAuth2Response.getEmail())
.role("ROLE_USER")
.build();
userRepository.save(user);
} else {
role = userData.getRole();
userData.setEmail(oAuth2Response.getEmail());
userRepository.save(userData);
}
return new CustomOAuth2User(oAuth2Response, role);
}
}