0. 네이버 개발자 설정
다음 네이버 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 로그인 연동

















댓글 ( 4)
댓글 남기기