1) single sign up
redirect로 a 사이트가 아니라 네이버 사이트에 가서 로그인을 하게 한다.
로그인 성공하면 a 사이트로 다시 돌아가야 하니깐 네이버에서 네이버에 지정된 적절한 callback url(a 사이트 로그인 성공 페이지 혹은 정보 받는 페이지 ..)
네이버 설정 이후 build.gradle 추가
implementation 'org.springframework.boot:spring-boot-starter-oauth2-client'
spring:
datasource:
url: jdbc:h2:mem:testdb
driver-class-name: org.h2.Driver
username: sa
password: password
jpa:
database: h2
database-platform: org.hibernate.dialect.H2Dialect
security:
oauth2:
client:
registration:
naver: # 원하는 서비스
client-id: <your_client_id>
client-secret: <your_client_secret>
redirect-uri: "{baseUrl}/{action}/oauth2/code/{registrationId}"
# 처음에 요청 보내고 다시 access token 어디로 전달할 지에 대한
authorization-grant-type: authorization_code
scope: email
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
#사용자 정보가 들어올 때
#json 응답으로 돌아오면 적절 키값 (ex 카카오)
#네이버는 response {.. } 형태로 돌아옴
NaverService
@Override
public OAuth2User loadUser(OAuth2UserRequest userRequest) throws OAuth2AuthenticationException {
OAuth2UserService<OAuth2UserRequest, OAuth2User> delegate = new DefaultOAuth2UserService();
OAuth2User oAuth2User = delegate.loadUser(userRequest);
//사용자의 정보가 들어올 객체
//네이버에서 사용자의 정보를 request 요청을 받는다
String registrationId = userRequest.getClientRegistration().getRegistrationId();
String userNameAttributeName = userRequest.getClientRegistration().getProviderDetails().getUserInfoEndpoint().getUserNameAttributeName();
security
@Override
protected void configure(HttpSecurity http) throws Exception {
http
.authorizeRequests()
.antMatchers(
"/home/**",
"/user/signup/**",
"/",
"/css/**",
"/images/**",
"/js/**"
)
.anonymous()
.anyRequest()
.authenticated()
.and()
.formLogin()
.loginPage("/user/login")
.defaultSuccessUrl("/home")
.permitAll()
.and()
.oauth2Login()//네이버에서 로그인되면 우리에서도 로그인된 것으로 처리
.userInfoEndpoint()
.userService(this.oAuth2UserService) //네이버에서의 유저정보가 우리 유저정보에도 저장이 된다
.and()
.defaultSuccessUrl("/home")
.and()
.logout()
.logoutUrl("/user/logout")
.logoutSuccessUrl("/home")
.deleteCookies("JSEESIONID")
.invalidateHttpSession(true)
.permitAll()
.and()
.oauth2Client()
;
}
=> email을 추가적으로 받아옴
@Service
public class NaverOAuth2Service implements OAuth2UserService<OAuth2UserRequest, OAuth2User> {
private final UserRepository userRepository;
public NaverOAuth2Service(
@Autowired
UserRepository userRepository,
@Autowired
HttpSession httpSession
) {
this.userRepository = userRepository;
}
@Override
public OAuth2User loadUser(OAuth2UserRequest userRequest) throws OAuth2AuthenticationException {
OAuth2UserService<OAuth2UserRequest, OAuth2User> delegate = new DefaultOAuth2UserService();
OAuth2User oAuth2User = delegate.loadUser(userRequest);
//사용자의 정보가 들어올 객체
//네이버에서 사용자의 정보를 request 요청을 받는다
String registrationId = userRequest.getClientRegistration().getRegistrationId();
String userNameAttributeName = userRequest.getClientRegistration().getProviderDetails().getUserInfoEndpoint().getUserNameAttributeName();
Map<?, ?> refinedAttributes = (Map<?, ?>) oAuth2User.getAttributes().get("response");
UserEntity user = new UserEntity();
user.setUsername((String) refinedAttributes.get("email"));
return new DefaultOAuth2User(
Collections.singleton(new SimpleGrantedAuthority("ROLE_USER")), //권한 설정해주기
(Map<String, Object>) refinedAttributes,
"email");
}
}
(+) 네이버 response
{
"resultcode": "00",
"message": "success",
"response": {
"email": "openapi@naver.com",
"nickname": "OpenAPI",
"profile_image": "https://ssl.pstatic.net/static/pwe/address/nodata_33x33.gif",
"age": "40-49",
"gender": "F",
"id": "32742776",
"name": "오픈 API",
"birthday": "10-01",
"birthyear": "1900",
"mobile": "010-0000-0000"
}
}