(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 |
---|