카테고리 없음

[NAVER API] 로그인 구현 (2)

제주니어 2022. 10. 29. 11:21

*Spring Framework를 사용한 기능 구현

*kakao login 진행 흐름에 따라 작성 하였으며, 내용이 길어지는 것을 방지하기 위해

MemberService와 MemberMapper 를 생략하였음을 알려드립니다.  

naver login

 

pom.xml

  • dependency를 추가한다. 
<dependency>
    <groupId>com.github.scribejava</groupId>
    <artifactId>scribejava-core</artifactId>
    <version>2.8.1</version>
</dependency>

NaverLoginApi.java

package com.finalproject.petkage.member.model.service;

import org.springframework.stereotype.Component;

import com.github.scribejava.core.builder.api.DefaultApi20;

@Component
public class NaverLoginApi extends DefaultApi20{
	protected NaverLoginApi(){
	}
	private static class InstanceHolder{
		private static final NaverLoginApi INSTANCE = new NaverLoginApi();
	}
	public static NaverLoginApi instance(){
		return InstanceHolder.INSTANCE;
	}
	@Override
	public String getAccessTokenEndpoint() {
		return "https://nid.naver.com/oauth2.0/token?grant_type=authorization_code";
	}
	@Override
	protected String getAuthorizationBaseUrl() {
		return "https://nid.naver.com/oauth2.0/authorize";
	}
}

NaverLoginBO.java

package com.finalproject.petkage.member.model.vo;

import java.io.IOException;
import java.util.UUID;

import javax.servlet.http.HttpSession;

import org.springframework.util.StringUtils;

import com.finalproject.petkage.member.model.service.NaverLoginApi;
import com.github.scribejava.core.builder.ServiceBuilder;
import com.github.scribejava.core.model.OAuth2AccessToken;
import com.github.scribejava.core.model.OAuthRequest;
import com.github.scribejava.core.model.Response;
import com.github.scribejava.core.model.Verb;
import com.github.scribejava.core.oauth.OAuth20Service;

public class NaverLoginBO {
	 
    /* 인증 요청문을 구성하는 파라미터 */
    //client_id: 애플리케이션 등록 후 발급받은 클라이언트 아이디
    //response_type: 인증 과정에 대한 구분값. code로 값이 고정돼 있습니다.
    //redirect_uri: 네이버 로그인 인증의 결과를 전달받을 콜백 URL(URL 인코딩). 애플리케이션을 등록할 때 Callback URL에 설정한 정보입니다.
    //state: 애플리케이션이 생성한 상태 토큰
    private final static String CLIENT_ID = "Client ID";
    private final static String CLIENT_SECRET = "Client Secret";
    private final static String REDIRECT_URI = "http://localhost:8083/petkage/member/callbackNaver";
    private final static String SESSION_STATE = "oauth_state";
    /* 프로필 조회 API URL */
    private final static String PROFILE_API_URL = "https://openapi.naver.com/v1/nid/me";
    
    /* 네이버 아이디로 인증  URL 생성  Method */
    public String getAuthorizationUrl(HttpSession session) {
 
        /* 세션 유효성 검증을 위하여 난수를 생성 */
        String state = generateRandomString();
        /* 생성한 난수 값을 session에 저장 */
        setSession(session,state);        
 
        /* Scribe에서 제공하는 인증 URL 생성 기능을 이용하여 네아로 인증 URL 생성 */
        OAuth20Service oauthService = new ServiceBuilder()                                                   
						            .apiKey(CLIENT_ID)
						            .apiSecret(CLIENT_SECRET)
						            .callback(REDIRECT_URI)
						            .state(state) //앞서 생성한 난수값을 인증 URL생성시 사용함
						            .build(NaverLoginApi.instance());
 
        return oauthService.getAuthorizationUrl();
    }
 
    /* 네이버아이디로 Callback 처리 및  AccessToken 획득 Method */
    public OAuth2AccessToken getAccessToken(HttpSession session, String code, String state) throws IOException{
 
        /* Callback으로 전달받은 세선검증용 난수값과 세션에 저장되어있는 값이 일치하는지 확인 */
        String sessionState = getSession(session);
        if(StringUtils.pathEquals(sessionState, state)){
 
            OAuth20Service oauthService = new ServiceBuilder()
					                    .apiKey(CLIENT_ID)
					                    .apiSecret(CLIENT_SECRET)
					                    .callback(REDIRECT_URI)
					                    .state(state)
					                    .build(NaverLoginApi.instance());
 
            /* Scribe에서 제공하는 AccessToken 획득 기능으로 네아로 Access Token을 획득 */
            OAuth2AccessToken accessToken = oauthService.getAccessToken(code);
            return accessToken;
        }
        return null;
    }
 
    /* 세션 유효성 검증을 위한 난수 생성기 */
    private String generateRandomString() {
        return UUID.randomUUID().toString();
    }
 
    /* http session에 데이터 저장 */
    private void setSession(HttpSession session,String state){
        session.setAttribute(SESSION_STATE, state);     
    }
 
    /* http session에서 데이터 가져오기 */ 
    private String getSession(HttpSession session){
        return (String) session.getAttribute(SESSION_STATE);
    }
    /* Access Token을 이용하여 네이버 사용자 프로필 API를 호출 */
    public String getUserProfile(OAuth2AccessToken oauthToken) throws IOException{
 
        OAuth20Service oauthService = new ServiceBuilder()
					                 .apiKey(CLIENT_ID)
					                 .apiSecret(CLIENT_SECRET)
					                 .callback(REDIRECT_URI).build(NaverLoginApi.instance());
 
        OAuthRequest request = new OAuthRequest(Verb.GET, PROFILE_API_URL, oauthService);
        
        oauthService.signRequest(oauthToken, request);
        Response response = request.send();
        return response.getBody();
    }
}
  • REDIRECT_URI에는 네이버 개발자센터에 등록했던 Callback URL를 입력한다.
  •  

  • 위 과정을 통해 네이버 API 사용 인증을 가져오며 네이버 계정에 따라 회원 프로필 정보를 얻어온다.
  • API Key를 입력하는 부분은 보안을 위해 properties 파일로 개별 관리 해도 되지만 우선 직접 처리하도록 구성했다.

MemberController.java

/* NAVER */
// NaverLoginBO
private NaverLoginBO naverLoginBO;

private String apiResult = null;

@Autowired
private void setNaverLoginBO(NaverLoginBO naverLoginBO) {
    this.naverLoginBO = naverLoginBO;
}
  • controller 상단에 추가한다.

MemberController("/loginPage").java

public String loginPage(Model model,HttpSession session) {
    log.info("로그인 페이지 요청");

    /* 네이버아이디로 인증 URL을 생성하기 위하여 naverLoginBO클래스의 getAuthorizationUrl메소드 호출 */
    String naverAuthUrl = naverLoginBO.getAuthorizationUrl(session);
    System.out.println("네이버: " + naverAuthUrl);

    //네이버 
    model.addAttribute("url", naverAuthUrl);

    return "member/login";
}
  • 네이버 로그인 버튼이 있는 로그인 페이지를 요청할 때 미리 만들어 놓은 NaverloginBO에서 session을 불러와 변수에 저장한다. 

  • 위 값은 model을 통해 네이버 로그인 페이지로 넘어가도록 설정한다. 

login.jsp

<button type="button" class="btn btn-block" id="naver_id_login" onclick="location.href='${url}'">
    네이버로 로그인
</button>

  • 네이버 로그인 버튼을 클릭하면 넘겨 받은 url 주소로 넘어가 네이버 로그인 창이 열린다. 

  • 테스트 ID로 등록된 계정으로 로그인 하면 네이버 개발자센터에서 사전 등록한 넘겨 받을 개인 정보 관련 동의 항목이 열린다.