SpringBoot와 AWS로 혼자 구현하는 웹서비스
SpringBoot 환경에서 네이버 로그인 연동하기
1. 네이버 개발자 페이지를 통해서 애플리케이션을 등록합니다
애플리케이션 이름을 등록하고 필요한 정보를 선택합니다.
로그인 API를 사용할 환경을 선택하고 여기서는 웹 서비스이므로 PC 웹, 로컬에서 돌리기 때문에 localhost로 설정했습니다.
2. SpringBoot 프로퍼티 설정
spring:
security:
oauth2:
client:
registration:
naver:
client-id: client 아이디
client-secret: client secret
redirect-uri: '{baseUrl}/{action}/oauth2/code/{registrationId}'
authorization_grant_type: authorization_code
scope: name, email, profile_image
client-name: Naver
provider:
naver:
authorization_uri: https://nid.naver.com/oauth2.0/authorize
token_uri: https://nid.naver.com/oauth2.0/token
user-info-uri: https://openapi.naver.com/v1/nid/me
user_name_attribute: response
3. SpringBoot OAuth2UserService 설정하기
package com.example.springbootAWS.config.auth;
import com.example.springbootAWS.config.auth.dto.OAuthAttributes;
import com.example.springbootAWS.config.auth.dto.SessionUser;
import com.example.springbootAWS.domain.user.Member;
import com.example.springbootAWS.domain.user.UserRepository;
import lombok.RequiredArgsConstructor;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
import org.springframework.security.oauth2.client.userinfo.DefaultOAuth2UserService;
import org.springframework.security.oauth2.client.userinfo.OAuth2UserRequest;
import org.springframework.security.oauth2.client.userinfo.OAuth2UserService;
import org.springframework.security.oauth2.core.OAuth2AuthenticationException;
import org.springframework.security.oauth2.core.user.DefaultOAuth2User;
import org.springframework.security.oauth2.core.user.OAuth2User;
import org.springframework.stereotype.Service;
import javax.servlet.http.HttpSession;
import java.util.Collections;
@RequiredArgsConstructor
@Service
public class CustomOAuth2UserService implements OAuth2UserService<OAuth2UserRequest, OAuth2User> {
private final UserRepository userRepository;
private final HttpSession httpSession;
@Override
public OAuth2User loadUser(OAuth2UserRequest userRequest) throws OAuth2AuthenticationException {
OAuth2UserService<OAuth2UserRequest, OAuth2User> delegate = new DefaultOAuth2UserService();
OAuth2User oAuth2User = delegate.loadUser(userRequest);
String registrationId = userRequest.getClientRegistration().getRegistrationId(); // 로그인 서비스 구분
String userNameAttributeName = userRequest.getClientRegistration().getProviderDetails()
.getUserInfoEndpoint().getUserNameAttributeName();
OAuthAttributes attributes = OAuthAttributes.of(registrationId, userNameAttributeName, oAuth2User.getAttributes());
Member member = saveOrUpdate(attributes);
httpSession.setAttribute("user", new SessionUser(member)); // 세션에 저장
return new DefaultOAuth2User(Collections.singleton(new SimpleGrantedAuthority(member.getRoleKey())), attributes.getAttributes(), attributes.getNameAttributeKey());
}
private Member saveOrUpdate(OAuthAttributes attributes) {
Member member = userRepository.findByEmail(attributes.getEmail())
.map(entity -> entity.update(attributes.getName(), attributes.getPicture()))
.orElse(attributes.toEntity());
return userRepository.save(member);
}
}
OAuth2User 객체에 로그인을 통해 받은 유저의 정보들이 들어있습니다.
해당 정보를 로그인 종류에 따라 구분할 수 있습니다. (여기서는 구글 로그인이 함께 사용되어있어서 구분 필요)
Login 정보를 받을 객체
package com.example.springbootAWS.config.auth.dto;
import com.example.springbootAWS.domain.user.Member;
import com.example.springbootAWS.domain.user.Role;
import lombok.Builder;
import lombok.Getter;
import java.util.Map;
@Getter
public class OAuthAttributes {
private Map<String, Object> attributes;
private String nameAttributeKey;
private String name;
private String email;
private String picture;
@Builder
public OAuthAttributes(Map<String, Object> attributes, String nameAttributeKey, String name, String email, String picture) {
this.attributes = attributes;
this.nameAttributeKey = nameAttributeKey;
this.name = name;
this.email = email;
this.picture = picture;
}
// google attribute 변환 과정
public static OAuthAttributes of(String registrationId, String userNameAttributeName, Map<String, Object> attributes) {
if ("naver".equals(registrationId)) {
return ofNaver("id", attributes);
}
return ofGoogle(userNameAttributeName, attributes);
}
private static OAuthAttributes ofGoogle(String userNameAttributeName, Map<String, Object> attributes) {
return OAuthAttributes.builder()
.name((String) attributes.get("name"))
.email((String) attributes.get("email"))
.picture((String) attributes.get("picture"))
.attributes(attributes)
.nameAttributeKey(userNameAttributeName)
.build();
}
private static OAuthAttributes ofNaver(String userNameAttributeName, Map<String, Object> attributes) {
Map<String, Object> response = (Map<String, Object>) attributes.get("response");
return OAuthAttributes.builder()
.name((String) response.get("name"))
.email((String) response.get("email"))
.picture((String) response.get("profile_image"))
.attributes(response)
.nameAttributeKey(userNameAttributeName)
.build();
}
public Member toEntity() {
return Member.builder()
.name(name)
.email(email)
.picture(picture)
.role(Role.GUEST)
.build();
}
}
'Java > Spring' 카테고리의 다른 글
[SpringBoot] 스프링 시큐리티 OAuth2 구글 로그인 API 연동하기 (0) | 2023.08.17 |
---|---|
[Spring Boot] 스프링 부트 mustache 한글 깨짐 현상 (0) | 2023.08.08 |
[SpringBoot] SpringBoot에서 JPA 사용하기 (0) | 2023.08.05 |
[Spring] JPA 란 무엇인가 (정의, 장단점) (0) | 2023.06.01 |
Springboot 환경에서 @Async와 ThreadPoolTaskExecutor (0) | 2023.05.26 |