(1) 
porm.xml에 라이브러리 추가
<ScribeJava>
==> 웹서비스를 제작할 때 다양한 SNS 서비스의 OAuth를 이용하는 경우가 많은데
이것들을 하나로 처리할 수 있는 통합 라이브러리입니다.


<!-- Naver  -->
<dependency>
<groupId>com.github.scribejava</groupId>
<artifactId>scribejava-core</artifactId>
<version>2.8.1</version>
</dependency>    

servlet-context.xml 에 beans에 naver Bo 추가
<beans:bean id="naverLoginBO" class="test.domain.NaverLoginBO" />


(2) NaverLoginBO.java 클래스 생성

package main.naver.com;

import java.io.IOException;
import java.util.UUID;
import javax.servlet.http.HttpSession;

import org.springframework.beans.factory.annotation.Value;
import org.springframework.util.StringUtils;
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;
    private String CLIENT_ID = "ID";
    
    // 발급받은 client Secret
    private String CLIENT_SECRET="SECRET";

    // 로그인성공시 리턴될 URL
    private String REDIRECT_URI="http://localhost:8080/mytest/member/oauth_naver";
    
    // 세션 유효값검증용 체크용
    private String SESSION_STATE = "oauth_state"; 

    // 프로필 조회 API URL
    private final static String PROFILE_API_URL = "https://openapi.naver.com/v1/nid/me";

    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();
    }

    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(HttpSession session, 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();
    }
}

(3) NaverLoginApi 클래스 생성

package main.naver.com;

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

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";
    }
}

(4) 컨트롤러

@RequestMapping("/navergo")
	public @ResponseBody String getNaverAuthUrl(HttpSession session) throws Exception {
	    String reqUrl = (new NaverLoginBO()).getAuthorizationUrl(session);
	    return reqUrl;
	}
	 

	// 네이버 연동정보 조회
	@RequestMapping(value = "/oauth_naver")
	public String oauthNaver(HttpServletRequest request, HttpServletResponse response) throws Exception {
	    JsonParser parser = new JsonParser();
	    Gson gson = new Gson();

	    HttpSession session = request.getSession();
	    String code = request.getParameter("code");
	    String state = request.getParameter("state");
	    String error = request.getParameter("error");
	    
	    // 로그인 팝업창에서 취소버튼 눌렀을경우
	    if ( error != null ){
	        if(error.equals("access_denied")){
	            return "redirect:/login";
	        }
	    }

	    OAuth2AccessToken oauthToken;
	    oauthToken = new NaverLoginBO().getAccessToken(session, code, state);
	    //로그인 사용자 정보를 읽어온다.
	    String loginInfo = new NaverLoginBO().getUserProfile(session, oauthToken);
	    System.out.println(loginInfo);
	    // JSON 형태로 변환
	    Object obj = parser.parse(loginInfo);
	    JsonObject jsonObj = (JsonObject)obj;
	    JsonObject callbackResponse = (JsonObject) jsonObj.get("response");
	    String naverUniqueNo = callbackResponse.get("id").toString();
	    
	    
	    if (naverUniqueNo != null && !naverUniqueNo.equals("")) {
	    	System.out.println(naverUniqueNo);
	    	
	        /** 
	            TO DO : 리턴받은 naverUniqueNo 해당하는 회원정보 조회 후 로그인 처리 후 메인으로 이동
	        */
	    	return "/member/login";
	    // 네이버 정보조회 실패
	    } else {
	        throw new Exception("네이버 정보조회에 실패했습니다.");
	    }

	}

(5)view 네이버로그인 JS

<script>
	$("#naverLoginGo").on("click",function(){
	    $.ajax({
	        url: 'navergo',
	        type: 'get',
	        success: function(res){
		    	 location.href = res;
		    },
			error : function(req, status, error){
                console.log("에러");
                console.log(req.responseText);
        	}
	    
		});
	    })
</script>

'API 적용해보기' 카테고리의 다른 글

스프링에 썸머노트 적용해보기  (0) 2022.01.16

+ Recent posts