지난시간 : 스크립트 이용하여 로그인을 해보았다! 오늘은 oauth 2.0 버전을 이용하여 로그인을 해보자!
네이버 로그인 흐름도

1. 디비접속 lettnemplyrinfo에 네이버, 카카오에서 주는 ID KEY값이 길기 때문에 varchar를 20에서 60으로 변경

2. 키 발급 네이버 개발자센터 접속 후 로그인을 해준다. ->application 제한이 있다!
https://developers.naver.com/main/
NAVER Developers
네이버 오픈 API들을 활용해 개발자들이 다양한 애플리케이션을 개발할 수 있도록 API 가이드와 SDK를 제공합니다. 제공중인 오픈 API에는 네이버 로그인, 검색, 단축URL, 캡차를 비롯 기계번역, 음
developers.naver.com

3. 처음 들어가는 장면에는 인증을 해야한다.!




+ 팀원들도 넣을 수 있음!

+ 참고용!

4.pom.xml에서 auto 사용하기 위해 라이브러리를 작성
<!-- 네이버 로그인 -->
<dependency>
<groupId>com.googlecode.json-simple</groupId>
<artifactId>json-simple</artifactId>
<version>1.1.1</version>
</dependency>
<!-- oauth2 login -->
<dependency>
<groupId>com.github.scribejava</groupId>
<artifactId>scribejava-apis</artifactId>
<version>5.6.0</version>
</dependency>
<dependency>
<groupId>com.github.scribejava</groupId>
<artifactId>scribejava-core</artifactId>
<version>2.8.1</version>
</dependency>
<dependency>
<groupId>com.squareup.okhttp3</groupId>
<artifactId>okhttp</artifactId>
<version>4.2.2</version>
</dependency>
<!-- //네이버 로그인 -->
5 .globals.properties 역할 : 내 로컬만을 위한 값을 넣는 곳이 Globals.properties
참고) context-properties 썸네일 이미지 사이즈 조정할때 사용했었음
context-properties는 공통적인 것 업데이트를 해도 다른 사람들이 전혀 지장이 없는 것
예) api주소
공통점: 설정을 저장하는 곳

6. 네이버에서 발급받았던 id와 key를 넣어준다,


7. 주석을 해제 후 빨간 밑줄이 뜨는 부분을 import해 받아준다.


8. Global.java에 아래와 같이 추가해준다.


9. let 아래 api.naver.service package를 생성한다. (imple도 함께)

9-1) NaverLoginApi.java파일을 아래와 같이 작성해준다.
package egovframework.let.api.naver.service;
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";
}
}
9-2) NaverLoginService 파일을 아래와 같이 작성해준다.
package egovframework.let.api.naver.service;
import java.io.IOException;
import javax.servlet.http.HttpSession;
import com.github.scribejava.core.model.OAuth2AccessToken;
public interface NaverLoginService {
/* 네이버 아이디로 인증 URL 생성 Method */
String getAuthorizationUrl(HttpSession session, String domain);
/* 네이버 아이디로 Callback 처리 및 AccessToken 획득 Method */
OAuth2AccessToken getAccessToken(HttpSession session, String code, String state, String domain) throws IOException;
/* 세션 유효성 검증을 위한 난수 생성기 */
String generateRandomString();
/* http session에 데이터 저장 */
void setSession(HttpSession session, String state);
/* http session에서 데이터 가져오기 */
String getSession(HttpSession session);
/* Access Token을 이용하여 네이버 사용자 프로필 API를 호출 */
String getUserProfile(OAuth2AccessToken oauthToken) throws IOException;
}
9-3) impl package를 만들어 그안에 serviceimpl.java를 만든다.
package egovframework.let.api.naver.service.impl;
import java.io.IOException;
import java.util.UUID;
import javax.servlet.http.HttpSession;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;
import com.github.scribejava.core.builder.ServiceBuilder;
import com.github.scribejava.core.model.OAuth2AccessToken;
import com.github.scribejava.core.oauth.OAuth20Service;
import egovframework.com.cmm.service.Globals;
import egovframework.let.api.naver.service.NaverLoginApi;
import egovframework.let.api.naver.service.NaverLoginService;
import egovframework.rte.fdl.cmmn.EgovAbstractServiceImpl;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.Response;
@Service("naverLoginService")
public class NaverLoginServiceImpl extends EgovAbstractServiceImpl implements NaverLoginService {
/*인증 요청문을 구성하는 파라미터*/
private final static String CLIENT_ID = Globals.NAVER_CLIENTID;
private final static String CLIENT_SECRET = Globals.NAVER_CLIENTSECRET;
private final static String REDIRECT_URI = Globals.NAVER_REDIRECTURI;
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 domain) {
String redirectUri = "http://" +domain + REDIRECT_URI;
/*세션 유효성 검증을 위하여 난수를 생성*/
String state = generateRandomString();
/*생성한 난수 값을 session에 저장*/
setSession(session, state);
/*Scribe에서 제공하는 인증 url 생성 기능을 이용하여 네아로 인증 url 생성*/
OAuth20Service oauthService = new ServiceBuilder()
.apiKey(CLIENT_ID)
.apiSecret(CLIENT_SECRET)
.callback(redirectUri)
.state(state)
.build(NaverLoginApi.instance());
return oauthService.getAuthorizationUrl();
}
/*네이버 아이디로 callback 처리 및 AccessToken 획득 Method*/
public OAuth2AccessToken getAccessToken(HttpSession session, String code, String state, String domain) throws IOException {
String redirectUri = "http://" + domain + REDIRECT_URI;
/*callback으로 전달받은 세션검증용 난수값과 세션에 저장되어있는 값이 일치하는지 확인*/
String sessionState = getSession(session);
if(StringUtils.pathEquals(sessionState, state)) {
OAuth20Service oauthService= new ServiceBuilder()
.apiKey(CLIENT_ID)
.apiSecret(CLIENT_SECRET)
.callback(redirectUri)
.build(NaverLoginApi.instance());
/*Scribe에서 제공하는 AccessToken 획득 기능으로 네아로 Access Token을 획득*/
OAuth2AccessToken accessToken = oauthService.getAccessToken(code);
return accessToken;
}
return null;
}
/*세션 유효성 검증을 위한 난수 생성기*/
public String generateRandomString() {
return UUID.randomUUID().toString();
}
/*http session 데이터 저장*/
public void setSession(HttpSession session, String state) {
session.setAttribute(SESSION_STATE, state);
}
/*http session에서 데이터 가져오기*/
public String getSession(HttpSession session) {
return (String) session.getAttribute(SESSION_STATE);
}
/*Access Token을 이용하여 네이버 사용자 프로필 api를 호출*/
public String getUserProfile(OAuth2AccessToken oauthToken) throws IOException{
OkHttpClient client = new OkHttpClient().newBuilder().build();
Request request = new Request.Builder()
.url(PROFILE_API_URL)
.method("GET", null)
.addHeader("Content-Type","application/x-www-form-urlencoded")
.addHeader("Authorization", "Bearer" + oauthToken.getAccessToken())
.build();
Response response = client.newCall(request).execute();
return response.body().string();
}
}
10. joinController에 네이버 로그인서비스를 연결해준다.

11. MemberType.jsp에 아래 코드를 추가해준다.
참고) 미리 네이버 로고를 다운받아 asset/front/images에 넣어준다.
<a class="btn-naver" href="${naverAuthUrl}" data-type="join">
<img src="/asset/front/images/btn-naver.png" width="150" alt="네이버 로그인 버튼"/>
</a>


12. 네이버 로그인 창이 뜨면 전체동의 box가 뜨는데 동의하면 오류가 뜬다.
왜? controller를 작성해주지 않아서 그래!


13.return 받은거에 대한 로직을 짜야해서 LoginController에 아래와 같이 로그인 콜백 코드를 추가한다.
//네이버 로그인 콜백
@RequestMapping(value="/login/naverLogin.do")
public String naverLogin(@ModelAttribute("loginVO") LoginVO loginVO, @RequestParam String code, @RequestParam String state, HttpSession session, HttpServletRequest request, HttpServletResponse response, Model model)
throws Exception {
String domain = request.getServerName();
OAuth2AccessToken oauthToken;
oauthToken = naverLoginService.getAccessToken(session, code, state, domain);
//로그인 사용자 정보를 읽어온다
String apiResult = naverLoginService.getUserProfile(oauthToken);
JSONParser parser = new JSONParser();
Object obj = parser.parse(apiResult);
JSONObject jsonObj = (JSONObject) obj;
JSONObject result=(JSONObject) jsonObj.get("response");
loginVO.setId("NAVER-" + result.get("id").toString());
loginVO.setPassword("");
loginVO.setUserSe("USR");
LoginVO resultVO = loginService.actionLogin(loginVO);
//로그인 값이 없으면 회원가입 처리
if (resultVO != null && resultVO.getId() != null && !resultVO.getId().equals("")) {
request.getSession().setAttribute("LoginVO", resultVO);
return "forward:/index.do";
}else {
//일반 가입을 제외하고는 ID 값은 SNS명 + id 값
JoinVO joinVO = new JoinVO();
joinVO.setEmplyrId(loginVO.getId());
joinVO.setUserNm(result.get("name").toString());
joinVO.setPassword("");
joinVO.setPasswordHint("SNS가입자");
joinVO.setPasswordCnsr("SNS가입자");
joinService.insertJoin(joinVO);
model.addAttribute("loginMessage", "회원가입이 완료되었습니다.");
return "forward:/index.do";
}
'Coding > 전자정부프레임' 카테고리의 다른 글
1.예약 프로그램 관리자 페이지 (0) | 2022.09.21 |
---|---|
예약관리 (0) | 2022.09.14 |
회원가입 (0) | 2022.08.17 |
게시판 : 페이징 루트 (0) | 2022.05.25 |
[전자정부프레임] Function tags(caontains,index of,startsWith, ) / formatting tag (fromatDate) (0) | 2022.04.27 |