본문 바로가기

개발/BACK

[SpringFramework] 스프링 프레임 워크 네이버 로그인(API) 연동 예제 2

728x90

 


네이버 로그인 연동 예제 1

https://hdhdeveloper.tistory.com/11

 

[SpringFramework] 스프링 프레임워크 네이버 로그인(API) 연동 예제_1

네이버 로그인 연동 예제 2 https://hdhdeveloper.tistory.com/12 SpringFramework 네이버 로그인(API) 연동 예제 2 지난 시간에 이어, 네이버 로그인 예제를 구현해보려고 한다. 먼저 네이버 로그인 인증 URL 을..

hdhdeveloper.tistory.com

 


 

지난 시간에 이어, 네이버 로그인 예제를 구현해보려고 한다.

먼저 네이버 로그인 인증 URL 을 생성하기 위한 메소드를 호출해야하는데 해당 메소드는 naverLoginVO에 들어있다.

naverLoginVO 와 naverLoginApi 클래스를 구현하자

 

 

1.

servlet-context.xml 설정  

   NaverloginVO  Class를 bean 객체로 설정

2.

NaverLoginVO.java 클래스 생성

   Client_ID 및 Client_secret 은 이전 편에 만들었던 [내 애플리케이션]에 들어가보면 다 나온다.

   해당 클래스의 getAuthorizationUrl() 메소드에서 인증 URL을 생성한다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
package main.naver.com;
 
 
import java.io.IOException;
import java.util.UUID;
import javax.servlet.http.HttpSession;
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 NaverLoginVO {
    /* 인증 요청문을 구성하는 파라미터 */
    //client_id: 애플리케이션 등록 후 발급받은 클라이언트 아이디
    //response_type: 인증 과정에 대한 구분값. code로 값이 고정돼 있습니다.
    //redirect_uri: 네이버 로그인 인증의 결과를 전달받을 콜백 URL(URL 인코딩). 애플리케이션을 등록할 때 Callback URL에 설정한 정보입니다.
    //state: 애플리케이션이 생성한 상태 토큰
    private final static String CLIENT_ID = "클라이언트 아이디";
    private final static String CLIENT_SECRET = "클라이언트 비밀번호";
    private final static String REDIRECT_URI = "http://localhost:8080/callback";
    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();
    }
}
 
cs

 

 

3.

NaverLoginApi.java

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
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";
    }
}
 
cs

해당 class 파일을 두 개 만들어서 생성된 프로젝트 구조

 

 

여기까지가 네이버 로그인 API를 연동하기 위한 기본 설정이 끝났다.

다음은 Controller에서 네이버 로그인 URL을 호출하기 위한 메소드를 호출해보자

 

naverAuthUrl이라는 변수를 선언해서 naverLoginVO에 있는 URL 생성 메소드를 호출했다.

해당 변수를 modelMap에 담아 home.jsp 페이지에 전달한다.

home.jsp 페이지에서 해당 코드를 작성한다.

a 태그에는 Controller에서 넘겨준 url 값을 하이퍼링크에 입력해주면 네이버 로그인 URL 페이지로 이동하게 된다.

 

 

 해당 URL로 이동하게 되면 [로그인연동_개발] 이라는 내 애플리케이션 명칭이 조회되고,

로그인을 누르면 redirect 페이지로 JSON 형태의 값들이 리턴된다.

 

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
//네이버 로그인 성공시 callback호출 메소드
    @RequestMapping(value = "/callback", method = { RequestMethod.GET, RequestMethod.POST })
    public String callback(Model model, @RequestParam String code, @RequestParam String state, HttpSession session) throws IOException, ParseException {
    OAuth2AccessToken oauthToken;
    oauthToken = naverLoginVO.getAccessToken(session, code, state);
    //1. 로그인 사용자 정보를 읽어온다.
    apiResult = naverLoginVO.getUserProfile(oauthToken); //String형식의 json데이터
    //2. String형식인 apiResult를 json형태로 바꿈
    JSONParser parser = new JSONParser();
    Object obj = null;
    try {
        obj = parser.parse(apiResult);
    } catch (org.json.simple.parser.ParseException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }
    JSONObject jsonObj = (JSONObject) obj;
    //3. 데이터 파싱
    //Top레벨 단계 _response 파싱
    JSONObject response_obj = (JSONObject)jsonObj.get("response");
    //response의 nickname값 파싱
    String user_name = (String)response_obj.get("nickname");
    String user_id = (String)response_obj.get("email");
    String user_phone =(String)response_obj.get("mobile");
    SessionConfigVO sessionConfigVO =new SessionConfigVO();
    sessionConfigVO.setUser_id(user_id);
    sessionConfigVO.setUser_name(user_name);
    sessionConfigVO.setUser_id(user_phone);
    sessionConfigVO.setNaver_login(true);
    //4.파싱 닉네임 세션으로 저장
    session.setAttribute("sessionConfigVO", sessionConfigVO);
    session.setAttribute("user_name", sessionConfigVO.getUser_name());
    return "redirect:/";
    }
cs

/callback으로 리턴되어진 데이터들은 JSON 형태로 값이 들어오기 때문에

데이터들을 파싱해서 사용해야한다.

 

나의 경우엔 네이버 로그인 유저VO와 프로젝트 내에 자체적인 UserVO를

같이 사용하기 위해 SessionConfigVO로 따로 클래스를 생성해서,

VO를 session에 보관하여 사용하려고 선언했다.

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
<div class="container">
        <div class="container-header">
        <input type="hidden" value="<c:out value='${sessionConfigVO.user_id }'/>" id="session_id"/>
            <c:if test="${sessionConfigVO ne null}">
                <ul style="height:30px;float:right;margin-bottom:20px;" class="fn-font">
                    <li><a style="color:blue;" class="" >${sessionConfigVO.user_name}' s come in</a></li>
                    <c:if test="${sessionConfigVO.naver_login eq true }">
                        <li>
                            <img src="../resources/images/naver_logo.png" style="width:30px;">
                            <a style="color:green;">NAVER 계정으로 접속중 </a>
                        </li>
                    </c:if>
                </ul>    
            </c:if>
        </div>
cs

결과물 : 

728x90