Spring Security 네이버 로그인

바그다드·2023년 4월 9일
0

Spring Security

목록 보기
11/17
  • OAuth2클라이언트의 provider마다 제공하는 값들의 키 값이 다르다. 예를 들어 providerId의 경우 구글은 sub로, facebook은 id라는 키 값으로 제공했다. 따라서 각 프로바이더에게 값을 제공 받기 위해서는 각 프로바이더의 공식 문서를 참조해볼 필요가 있다.
  • 이번에는 네이버 로그인을 구현해볼 것인데, 네이버는 기본적으로 OAuth2 제공자가 아니기 때문에 google이나 facebook처럼 엑세스토큰과 사용자 정보를 한번에 받은 방식과 달리, 인가 코드를 이용해 엑세스 토큰을 발급 받고 엑세스 토큰을 이용해 사용자 정보를 받는 방식으로 구현해야 한다.

application.properties 수정

spring.security.oauth2.client.registration.naver.client-id=
spring.security.oauth2.client.registration.naver.client-secret=
spring.security.oauth2.client.registration.naver.scope=name,email
spring.security.oauth2.client.registration.naver.client-name=Naver
spring.security.oauth2.client.registration.naver.authorization-grant-type=authorization_code
spring.security.oauth2.client.registration.naver.redirect-uri=http://localhost:8080/login/oauth2/code/naver
  • google과 facebook은 OAth2제공자이기 때문에 따로 redirect-uri를 명시하지 않아도 되지만 네이버는 기본 제공자가 아니기 때문에 redirect-uri를 명시해줘야 한다.

네이버 개발자 앱 등록

  1. 네이버 개발자 접속
  2. applications탭에서 애플리케이션 등록 선택
  3. 아래의 각 값들 채우기
  4. Callback URL에는 application.properties에 정의했던 redirect-url과 일치시켜주자!
  • 여기서 나는 등록하기를 눌러도 페이지 전환이 안되길래 에러가 발생해서 등록이 안되는건줄 알았는데 내 애플리케이션을 확인해보니 등록하기를 여러 번 눌러 몇개나 등록이 되어 있었다. 나처럼 페이지 전환이 안되는 사람들은 참고하자ㅜㅜ

  • 이제 이렇게 나온 id와 password를 application.properties의 각 설정에 넣어주고 프로젝트를 실행해보면 에러가 발생할 것이다. 그 중 에러 메세지 맨 윗줄 끝쪽을 봐보면 아래와 같은 에러가 발생하는걸 확인할 수 있는데, 네이버가 OAuth2 기본제공자가 아니기 때문에 네이버를 위한 설정을 추가해줘야 한다.
    - 네이버 같은 경우에는 임의로 설정이 가능하지만 OAuth2의 규칙을 따라서 작성해주자

application.properties에 provider 정보 추가

#naver를 OAuth2 provider로 추가
spring.security.oauth2.client.provider.naver.authorization-uri=https://nid.naver.com/oauth2.0/authorize
spring.security.oauth2.client.provider.naver.token-uri=https://nid.naver.com/oauth2.0/token
spring.security.oauth2.client.provider.naver.user-info-uri=https://openapi.naver.com/v1/nid/me
# 회원정보를 json으로 받는데 response라는 키값으로 네이버가 리턴해줌
spring.security.oauth2.client.provider.naver.user-name-attribute=response
  • 여기서 꽤 많은 시간을 잡아먹었는데, 기존에 yml로 작성되어 있던 것을 properties형식으로 바꿔서 작성했더니 아래 에러가 발생했다.
Provider ID must be specified for client registration 'naver'
  • 위의 코드를 보면 각 설정 값에 'spring.security.oauth2.client.provider.naver'라는 형식으로 provider정보를 추가해줘야 하는데 이를 빼먹어서 자꾸 에러가 발생한 것이었다ㅜㅜ
  • 참고로 아래 코드는 시큐리티 2.x버전 설정 코드이다. 참고만 하자
spring.security.oauth2.client.client-id=클라이언트id
spring.security.oauth2.client.client-secret=클라이언트암호
spring.security.oauth2.client.access-token-uri=https://nid.naver.com/oauth/token
spring.security.oauth2.client.user-authorization-uri=https://nid.naver.com/oauth/authorize
spring.security.oauth2.client.token-name=oauth_token
spring.security.oauth2.client.authentication-scheme=query
spring.security.oauth2.client.client-authentication-scheme=form
spring.security.oauth2.client.scope=name,email,profile_image
spring.security.oauth2.client.registered-redirect-uri=http://localhost:8080/login/oauth2/code/naver
spring.security.oauth2.client.pre-established-redirect-uri=http://localhost:8080/login/oauth2/code/naver
spring.security.oauth2.client.use-current-uri=false
spring.security.oauth2.client.enable-csrf=true
spring.security.oauth2.client.client-name=Naver
  • 이렇게 수정하고 네이버 로그인을 시도해보면 500에러가 발생하지만 콘솔을 확인해보면 제대로 값은 가져오는 것을 확인할 수 있다.

  • 이제 네이버 로그인 데이터도 처리해주자
  • 아래 패키지 위치에 OAuth2UserInfo의 구현체 NaverUserInfo를 생성해주자
package com.cos.security1.config.oauth.provider;

public class NaverUserInfo implements OAuth2UserInfo{

    private Map<String, Object> attributes; // oAuth2User.getAttributes()


    public NaverUserInfo(Map<String, Object> attributes) {
        this.attributes = attributes;
    }

    @Override
    public String getProviderId() {
        return (String) attributes.get("id");
    }

    @Override
    public String getProvider() {
        return "naver";
    }

    @Override
    public String getEmail() {
        return (String) attributes.get("email");
    }

    @Override
    public String getName() {
        return (String) attributes.get("name");
    }
}

PrincipalOauth2UserService 수정

  • loadUser메서드를 수정해주자
if (userRequest.getClientRegistration().getRegistrationId().equals("google")) {
            System.out.println("구글 로그인 요청");
            oAuth2UserInfo = new GoogleUserInfo(oAuth2User.getAttributes());
        } else if (userRequest.getClientRegistration().getRegistrationId().equals("facebook")) {
            System.out.println("페이스북 로그인 요청");
            oAuth2UserInfo = new FacebookUserInfo(oAuth2User.getAttributes());
        }else if (userRequest.getClientRegistration().getRegistrationId().equals("naver")) {
            System.out.println("네이버 로그인 요청");
            oAuth2UserInfo = new NaverUserInfo((Map) oAuth2User.getAttributes().get("response"));
        } else {
            System.out.println("우리는 구글과 페이스북만 지원해요!!!");
        }
  • 여기서 naver부분을 보면 naver만 attrebutes값중에 reponse값만 보내는것을 알 수 있는데
    앞에서 확인했던 naver의 attributes 값을 다시 확인해보자
getAttributes = {resultcode=00, message=success, response={id=9iNrO26qdPnjM7Kky8tCRBpnjMSzEaeZLejMnCj6p5Y, email=magicofclown@naver.com, name=박의민}}
  • attributes안에 response라는 json객체가 또 들어가 있고 그 안에 회원 정보가 들어가 있는 것을 알 수 있다. 따라서 NaverUserInfo생성자의 매개변수로 response값을 넣어준 것이다.
  • 이제 네이버 로그인을 다시 시도해보자
  • DB에 값이 제대로 들어있는걸 확인해 볼 수 있다!!

/user

principalDetails = User(id=4, username=naver_9iNrO26qdPnjM7Kky8tCRBpnjMSzEaeZLejMnCj6p5Y, 
password=$2a$10$Div1.ZrOPcuacW.IsoCsquu.Xg1xhNf0mg9fgaabusu8EBl7v2ywS, email=magicofclown@naver.com,
role=ROLE_USER, provider=naver, providerId=9iNrO26qdPnjM7Kky8tCRBpnjMSzEaeZLejMnCj6p5Y, 
loginDate=null, createDate=2023-04-09 21:08:34.098)
  • provider가 naver인걸 확인할 수 있다

google로그인

/user

principalDetails = User(id=2, username=google_105156291955329144943,
password=$2a$10$dzn6DiNSDQWIoxR.BTOiu.ztWb.YabV6fk8YZbqppeIF2DZpZQoja,
email=magicofclown@gmail.com, role=ROLE_USER, provider=google,
providerId=105156291955329144943, loginDate=null, createDate=2023-04-08 22:17:53.812)

-provider가 google인걸 확인할 수 있다.

  • 이상으로 스프링부트 기본 로그인 + OAuth2.0로그인을 통합해서 구현해 보았다!!
profile
꾸준히 하자!

0개의 댓글