스프링

 

 

 

0. 네이버 개발자 설정

 [SNS로그인 네이버 연동] 네아로 설정하는 방법

 

 

 

 

다음 네이버 api 사이트에서 js + html 로

https://developers.naver.com/docs/login/api/api.md

 

1. APIExamNaverLogin.html  과   callback.html  의 두페이지만 구현하면  끝이난다.

혹은  naverlogin.jsp  와  callback.jsp 페이지 이다.

 

나머지는 부수적으로 네이버에서 데이터를 가져오는 설정 값처리이며, 무엇보다  중요한것이 

APIExamNaverLogin.html  에서는 다음과 같이 간단하게    자바스크르립트로 처리후 callback.html  페이지에서 데이터를 가져올수 있으나

<script type="text/javascript">
        var naver_id_login = new naver_id_login("YOUR_CLIENT_ID", "YOUR_CALLBACK_URL");
        var state = naver_id_login.getUniqState();
        naver_id_login.setButton("white", 2,40);
        naver_id_login.setDomain("YOUR_SERVICE_URL");
        naver_id_login.setState(state);
        naver_id_login.setPopup();
        naver_id_login.init_naver_id_login();
    </script>

 

js 가 아닌 자바로 구현시 다음  naver 로그인 url 값이 생략되 있기 때문에  url 생성을 해줘야 한다.

즉, 접근토크 발급 요청 api 과정이라고 보면 된다. 

<a href="https://nid.naver.com/oauth2.0/authorize?
									response_type=code
									&client_id=O9St1pC9EAPKQRlsYeWN
									&state=state
									&redirect_uri=http://localhost:8081/c3t2/Naver" id="naverLogin">
				            		Naver 로그인
					        </a>

 

 

 

 

따라서, 스크립트는 의미없으며 주석 처리를 해도 작동 된다. 다만 로그인 버튼 디자인 처리를 위해 .

다음과 같은 코드만 넣도된다.

naver_id_login.setButton("white", 2,40); 

 

						<div class="naverLogin" id="naver_id_login">
							<a href="https://nid.naver.com/oauth2.0/authorize?
									response_type=code
									&client_id=네이버clinet_id
									&state=state
									&redirect_uri=http://localhost:8081/naver/callback" id="naverLogin">
				            		Naver 로그인
					        </a>
						</div>
						<script type="text/javascript">
						/* 	var naver_id_login = new naver_id_login("네이버clinet_id", "http://localhost:8080/naver/callback");
							var state = naver_id_login.getUniqState();
                                                         naver_id_login.setButton("white", 2,40);
							naver_id_login.setDomain("http://localhost:8081/c3t2");
							naver_id_login.setState(state);
							naver_id_login.setPopup();
							naver_id_login.init_naver_id_login(); */
						</script>
					</div>

 

 

 

 

 

 

 

 

 

 

 

1. 라이브러리

		<!--네이버 로그인 라이브러리-->
			<dependency>
				    <groupId>com.fasterxml.jackson.core</groupId>
				    <artifactId>jackson-databind</artifactId>
				    <version>2.12.3</version>
				</dependency>
			<!-- OAuth2.0 -->
			<dependency>
			    <groupId>com.github.scribejava</groupId>
			    <artifactId>scribejava-core</artifactId>
			    <version>2.8.1</version>
			</dependency>
			<!-- 제이슨 파싱 -->
			<dependency>
			    <groupId>com.googlecode.json-simple</groupId>
			    <artifactId>json-simple</artifactId>
			    <version>1.1.1</version>
			</dependency>

 

 

 

 

2.NaverVO

package com.korea.webtoon.util.oauth.naver;

import lombok.Data;
import lombok.ToString;

/**
 네이버 JSON  반환 처리 샘플값
{
    "resultcode": "00",
    "message": "success",
    "response": {
        "id": "11601227211",
        "nickname": "sample",
        "profile_image": "https:\/\test.jpg",
        "age": "20-29",
        "gender": "M",
        "email": "test1@naver.com",
        "name": "홍길도",
        "birthday": "07-28"
    }
}
*/
@Data
@ToString
@JsonIgnoreProperties(ignoreUnknown = true)
public class NaverVO {

	
	private String resultcode;
	
	private String message;
	
	private String id;
	
	private String nickname;
	
	private String profile_image;
	
	private String age;
	
	private String gender;
	
	private String email;
	
	private String name;
	
	private String birthday;
	
}

 

 

 

 

3. NaverOAuthApi

package com.korea.webtoon.util.oauth.naver;

import org.springframework.stereotype.Component;

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


@Component
public class NaverOAuthApi extends DefaultApi20 {

	@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.NaverLoginBO


import java.io.IOException;
import java.net.URLEncoder;
import java.nio.charset.Charset;
import java.util.UUID;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;
 
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
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.Verb;
import com.github.scribejava.core.oauth.OAuth20Service;
 
@Component
public class NaverOAuthLoginBO {
     
    /** 
        [[ 인증 요청문을 구성하는 파라미터]]
         1.client_id: 애플리케이션 등록 후 발급받은 클라이언트 아이디
         2.response_type: 인증 과정에 대한 구분값, code로 값이 고정
         3.redirect_uri: 네이버 로그인 인증의 결과를 전달받을 콜백 URL(URL 인코딩) 애플리케이션을 등록할 때 Callback URL에 설정한 정보
         4.state: 애플리케이션이 생성한 상태 토큰
     */
    private final static String CLIENT_ID = "클라이언트 아이디"; // 클라이언트 아이디
    private final static String CLIENT_SECRET = "클라이언트 시크릿"; // 클라이언트 시크릿
  //  private final static String REDIRECT_URI = "http://localhost:8080/naver/naverRedirect";
    private final static String SESSION_STATE = "oauth_state";
 

    
    /** 프로필 조회 API URL */
    private final static String PROFILE_API_URL = "https://openapi.naver.com/v1/nid/me";
 
    private final static String NAVER_REDIRECT  =	"/naver/naverRedirect";
   
    
    @Autowired
    private NaverOAuthApi naverOAuthApi;
 
    @Autowired
    private HttpServletRequest request;
     
    /** 네이버 아이디로 인증 URL 생성 Method */
    public String getAuthorizationUrl(HttpSession session) {
 
        /* 세션 유효성 검증을 위하여 난수를 생성 */
        String state = UUID.randomUUID().toString();
         
        /* 생성한 난수 값을 session에 저장 */
        session.setAttribute(SESSION_STATE, state);
 
        
        String DOMAIN	=	request.getScheme()+"://"+ request.getServerName() +":"+ request.getServerPort()+request.getContextPath();
		String  REDIRECT_URI=DOMAIN+NAVER_REDIRECT;	
		// REDIRECT_URI= URLEncoder.encode(REDIRECT_URI,  Charset.forName("UTF-8"));
		
		
        
        /* Scribe에서 제공하는 인증 URL 생성 기능을 이용하여 네아로 인증 URL 생성 */
        OAuth20Service oauthService = new ServiceBuilder().apiKey(CLIENT_ID).apiSecret(CLIENT_SECRET)
                .callback(REDIRECT_URI).state(state) // 앞서 생성한 난수값을 인증 URL생성시 사용함
                .build(naverOAuthApi);
 
        return oauthService.getAuthorizationUrl();
    }
 
     
     
     
    /** 네이버아이디로 Callback 처리 및 AccessToken 획득 Method */
    public OAuth2AccessToken getAccessToken(HttpSession session, String code, String state) throws IOException {
 
        String DOMAIN	=	request.getScheme()+"://"+ request.getServerName() +":"+ request.getServerPort()+request.getContextPath();
		String  REDIRECT_URI=DOMAIN+NAVER_REDIRECT;	
		// REDIRECT_URI= URLEncoder.encode(REDIRECT_URI,  Charset.forName("UTF-8"));
		 
    	
        /* Callback으로 전달받은 세선검증용 난수값과 세션에 저장되어있는 값이 일치하는지 확인 */
        String sessionState = (String) session.getAttribute(SESSION_STATE);
        if (StringUtils.pathEquals(sessionState, state)) {
            OAuth20Service oauthService = new ServiceBuilder().apiKey(CLIENT_ID).apiSecret(CLIENT_SECRET)
                    .callback(REDIRECT_URI).state(state).build(naverOAuthApi);
 
            /* Scribe에서 제공하는 AccessToken 획득 기능으로 네아로 Access Token을 획득 */
            return oauthService.getAccessToken(code);
        }
         
        return null;
    }
 
     
 
 
    /** Access Token을 이용하여 네이버 사용자 프로필 API를 호출 */
    public String getUserProfile(OAuth2AccessToken oauthToken) throws IOException {
        String DOMAIN	=	request.getScheme()+"://"+ request.getServerName() +":"+ request.getServerPort()+request.getContextPath();
		String  REDIRECT_URI=DOMAIN+NAVER_REDIRECT;	
		// REDIRECT_URI= URLEncoder.encode(REDIRECT_URI,  Charset.forName("UTF-8"));
    	
    	
        OAuth20Service oauthService = new ServiceBuilder().apiKey(CLIENT_ID).apiSecret(CLIENT_SECRET)
                .callback(REDIRECT_URI).build(naverOAuthApi);
 
        OAuthRequest request = new OAuthRequest(Verb.GET, PROFILE_API_URL, oauthService);
        oauthService.signRequest(oauthToken, request);
        return request.send().getBody();
    }
 
     
     
     
}

 

 

 

 

 

5.NaverController


import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;

import org.json.simple.JSONObject;
import org.json.simple.parser.JSONParser;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;

import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.github.scribejava.core.model.OAuth2AccessToken;
import NaverOAuthLoginBO;
import NaverVO;

import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
 
@Slf4j
@Controller
@RequiredArgsConstructor
@RequestMapping("/naver/")
public class NaverOAuthController {
 
    private final NaverOAuthLoginBO naverLoginBO;
     
 
    /** urlNaver 
     * 
     *   */
    @GetMapping("urlNaver")
    @ResponseBody
    public String login(Model model, HttpSession session) throws Exception { 
        /* 네아로 인증 URL을 생성하기 위하여 naverLoginBO클래스의 getAuthorizationUrl메소드 호출 */
        String naverAuthUrl = naverLoginBO.getAuthorizationUrl(session);
         
        /* 생성한 인증 URL을 View로 전달 */
        return naverAuthUrl;
    }
  
     
    /**   네이버 로그인 성공시 callback호출 메소드  */
    @GetMapping("/naverRedirect")
    public String callbackNaver(Model model, @RequestParam String code, @RequestParam String state, HttpServletRequest rqeust) throws Exception {             
        OAuth2AccessToken oauthToken;
        oauthToken = naverLoginBO.getAccessToken(rqeust.getSession(), code, state);
         
        // 로그인 사용자 정보를 읽어온다.
        String apiResult = naverLoginBO.getUserProfile(oauthToken);
        log.info("1.로그인 사용자 정보를 읽어온다  {}",apiResult );
         
        JSONParser jsonParser = new JSONParser();
        JSONObject jsonObj=(JSONObject) jsonParser.parse(apiResult);
        JSONObject responseObj = (JSONObject) jsonObj.get("response");
          
        // objectMapper 로 json NaverVO 객체 매핑 처리리
        ObjectMapper  mapper=new ObjectMapper();
        NaverVO naverVO = mapper.readValue(responseObj.toJSONString(), new TypeReference<NaverVO>() {});
        naverVO.setResultcode(jsonObj.get("resultcode").toString());
        naverVO.setMessage(jsonObj.get("message").toString());
         
        log.info("2.로그인 사용자 정보를 읽어온다 1 {}",naverVO.toString() );
             
        // 세션에 사용자 정보 등록
        rqeust.getSession().setAttribute("naverVO", naverVO);
 
        /* 네이버 로그인 성공 페이지 View 호출 */
        return "redirect:/";
    }
 
     
 
}

 

 

 

 

다음과 같이  ajax 로  urlNaver 값을 가져오는 것이  좋다.

    /** urlNaver 
     * 
     *   */
    @GetMapping("urlNaver")
    @ResponseBody
    public String login(Model model, HttpSession session) throws Exception { 
        /* 네아로 인증 URL을 생성하기 위하여 naverLoginBO클래스의 getAuthorizationUrl메소드 호출 */
        String naverAuthUrl = naverLoginBO.getAuthorizationUrl(session);
         
        /* 생성한 인증 URL을 View로 전달 */
        return naverAuthUrl;
    }
  

 

$(function(){		
	
	$("#modal_btn_login_submit").on("click", function(e){
				const HOME=$("#HOME").val();
				const member_id=$("#modal_login_id").val();
				const member_passwd=$("#modal_login_passwd").val();
				const rememberId=$("#modal_login_rememberId").is(":checked");
				
				console.log(" 로그인 파라미터 : ", member_id, member_passwd , rememberId);
				if(!member_id){
					alert("아이디를 입력해 주세요.");
					$("#id").focus();
					return;
				}
				
				if(!member_passwd){
					alert("비밀번호를 입력해 주세요.");
					$("#member_passwd").focus();
					return;
				}	
					
			 	$.ajax({
							type : "POST",
							data : {
								member_id,
								member_passwd,
								rememberId
							},
							url : `${HOME}/login/LoginPro`,
							success : function(res) {
								console.log("성공 :", res);		
								
								if(res=="admin_login"){
									location.href=`${HOME}/admin/admin_login`;
									return;
								}
								
								if(res.status=="failed"){
									alert(res.msg);								
									return;
								}else if(res.status=="success"){
									   //alert("로그인 성공");
									  location.href=`${HOME}/`;									
								}									
										
													
							},
							error:function(res){
								console.log("실패  :", res);
							}
		     });
			
	});
	
	
	
		
	
getNaverUrl();
});
//https://nid.naver.com/oauth2.0/authorize
//?response_type=code&client_id=esfsefse52324234
//&redirect_uri=http://localhost:8080/naver/naverRedirect&state=fsdfsdewwww
function getNaverUrl(){
		const HOME=$("#HOME").val();

		$.ajax({
					type : "GET",	
					url : `${HOME}/naver/urlNaver`,
					success : function(res) {
						console.log("urlNaver   :" ,res);
						$("#naverLogin").attr("href", res);		
					},
					error:function(res){
						console.log("실패  :", res);
					}
     });
	
}

 

 

 

 

 

 

 

 

 

 

 

6.login.jsp

<%@ page language="java" contentType="text/html; charset=UTF-8"
	pageEncoding="UTF-8"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>로그인</title>
<style type="text/css">
#container{width:500px}
.sns_join a.naver{border-color:#2db400}
.sns_join a{display:block;margin-top:10px;width:100%;height:50px;border:1px solid #000;font-size:15px;line-height:50px;text-align:center;background:#fff}
.sns_join a.naver>.icon{background:url(https://cdn.jsdelivr.net/gh/braverokmc79/ouath2-img@v1.0.0/images/icon_naver.png) no-repeat 0 0;background-size:18px auto}
.sns_join a>.icon{display:inline-block;margin:0 auto;padding-left:29px;width:188px;color:#666;font-size:15px;letter-spacing:-1px;line-height:20px;text-align:left}
</style>
</head>
<body>
	<div id="container">
		<div class="sns_join">
			<a class="naver" href="${urlNaver}" id="naver_id_login_anchor"> <span
				class="icon">네이버로 로그인</span>
			</a>
		</div>
	</div>
</body>
</html>

 

 

 

 

7.loginSuccess.jsp

<%@ page language="java" contentType="text/html; charset=UTF-8"
	pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>
			<div>
				<h1>환영합니다!</h1>
				<p>
					<span>${naverVO.name}</span>님의 로그인 성공<br> 이메일 주소는 <strong>${naverVO.email}</strong>입니다.
				</p>
			</div>
			<div>
				<a href="/">홈</a>
			</div>
</body>
</html>

 

 

 

 

DB 저장   mybais

 

	<insert id="saveOauthNaver">
	MERGE INTO WEBTOON_USER
		  USING DUAL ON (EMAIL = #{email} )
     WHEN MATCHED THEN
		  	UPDATE SET OAUTH = #{oauth} 
	 WHEN NOT MATCHED THEN
		    INSERT  (USER_IDX, NAME, ID,  EMAIL,  OAUTH) 
		                     VALUES( seq_user_idx.nextVal,
									#{name},
									#{id},
									#{email},
									#{oauth} 
									)	
	</insert>
	

 

 

 

 

 

참조 :  https://cobook.tistory.com/31

[Spring] 네이버 로그인 Open API

 

 

 

 

 

스프링 구글로그인 처리, Sns Google 로그인 연동

 

 

 

 

 

 

 

about author

PHRASE

Level 60  라이트

Lightly won, lightly held. (쉽게 얻은 것은 쉽게 잃는다.)

댓글 ( 4)

댓글 남기기

작성