네이버 로그인 (네아로) JAVA-API 적용하기
네이버 로그인 (네아로) JAVA-API
네이버아이디로 로그인 코딩 전, 네이버 개발자센터 https://developers.naver.com/main/ 가입후 오픈 API 이용 신청을 해야합니다.
API 신청 후 애플리케이션을 등록해 주세요.
애플리케이션 이름, 사용할 사용자 정보 등을 체크해 주세요.
애플리케이션을 등록하면 ClientID와 Client Secret을 발급받을 수 있습니다.
API 정보에서는 callback URL을 설정해주어야 합니다.
자세한 API 설명은 아래 URL을 확인하시면 됩니다.
https://developers.naver.com/
소스코딩 후에는 검수 요청을 해야 하니 진행되는 과정을 캡쳐 해두셔서 검수 때 이미지로 활용 하시면 되요!
소스코드는 아래 공유 합니다.
1. NaverLoginUtil.java
- 인증 토큰을 생성
public class NaverLoginUtil {
/* 인증 요청문을 구성하는 파라미터 */
//client_id: 애플리케이션 등록 후 발급받은 클라이언트 아이디
//response_type: 인증 과정에 대한 구분값. code로 값이 고정돼 있습니다.
//redirect_uri: 네이버 로그인 인증의 결과를 전달받을 콜백 URL(URL 인코딩). 애플리케이션을 등록할 때 Callback URL에 설정한 정보입니다.
//state: 애플리케이션이 생성한 상태 토큰
private final static String CLIENT_ID = "제공받은 CLIENT_ID";
private final static String CLIENT_SECRET = "제공받은 CLIENT_SECRET";
private final static String REDIRECT_URI = "https://도메인/naverLoginCallback";
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();
}
}
2. LoginCallback.java
- 인증받은 토큰으로 사용자 정보를 받아와서 로그인 처리~
//네이버 로그인 성공시 callback호출 메소드
@RequestMapping("naverLoginCallback")
public void naverLoginCallback(HttpServletRequest request, HttpServletResponse response, @RequestParam String code, @RequestParam String state, HttpSession session) throws Exception {
System.out.println("여기는 callback");
// response를 위한 정의
PrintWriter writer = response.getWriter();
int cnt = 0;
OAuth2AccessToken oauthToken;
oauthToken = naverLoginUtil.getAccessToken(session, code, state);
//1. 로그인 사용자 정보를 읽어온다.
String apiResult = naverLoginUtil.getUserProfile(oauthToken); //String형식의 json데이터
/** apiResult json 구조
{"resultcode":"00",
"message":"success",
"response":{"id":"33666449","nickname":"shinn****","age":"20-29","gender":"M","email":"sh@naver.com","name":"\uc2e0\ubc94\ud638"}}
**/
//2. String형식인 apiResult를 json형태로 바꿈
JSONParser parser = new JSONParser();
Object obj = parser.parse(apiResult);
org.json.simple.JSONObject jsonObj = (org.json.simple.JSONObject) obj;
//3. 데이터 파싱
//Top레벨 단계 _response 파싱
org.json.simple.JSONObject response_obj = (org.json.simple.JSONObject)jsonObj.get("response");
// 네이버에서 주는 고유 ID
String naverIfId = (String) response_obj.get("id");
// 네이버에서 설정된 사용자 이름
String naverName = (String) response_obj.get("name");
// 네이버에서 설정된 사용자 별명
String naverNickname = (String) response_obj.get("nickname");
// 네이버에서 설정된 이메일
String naverEmail = (String) response_obj.get("email");
// 네이버에서 설정된 사용자 프로필 사진
String naverProfileImage = (String) response_obj.get("profile_image");
// 랜덤숫자 자리수 초기화(2자리)
DecimalFormat decimal2Format = new DecimalFormat("00");
// 랜덤숫자 자리수 초기화(3자리)
DecimalFormat decimal3Format = new DecimalFormat("000");
// 랜덤숫자 자리수 초기화(4자리)
DecimalFormat decimal4Format = new DecimalFormat("0000");
// 회원정보 세팅
AivSignUpVO aivSignUpVO = new AivSignUpVO();
aivSignUpVO.getAivSignUpBean().setUserName(naverName);
aivSignUpVO.getAivSignUpBean().setUserEmail(naverEmail);
aivSignUpVO.getAivSignUpBean().setUserProfileUrl(naverProfileImage);
aivSignUpVO.getAivSignUpBean().setUserIfInfo("NAVER");
aivSignUpVO.getAivSignUpBean().setUserIfId(naverIfId);
boolean emailExists = false;
// 네이버에서 주는 고유 ID의 중복여부 체크(AIV_EMPLOYEE 테이블의 USER_IF_ID의 중복체크)
int existsUserIfIdCnt = aivSignUpService.selectExistsUserIfId(aivSignUpVO);
// 중복되는 ID가 없을 경우 신규가입으로 아래 구문을 실행
if(existsUserIfIdCnt == 0) {
int existEmailCnt = aivSignUpService.selectExistsUserEmail(aivSignUpVO);
if(existEmailCnt > 0) {
emailExists = true;
} else {
// 네이버에서 주는 고유 ID 세팅
aivSignUpVO.getAivSignUpBean().setUserId(naverIfId);
// USER_ID의 중복된 값이 있을 경우 반복문을 통하여 랜덤수를 뒤에 부여한 뒤 USER_ID를 새로 세팅해 줌
for(int i = 0; i < 10; i++) {
if(i > 0) {
// USER_ID가 중복된 경우 랜덤수 두 자리를 뒤에 부여해줌
naverIfId = naverIfId + "_" + decimal2Format.format(Math.random() * 99);
aivSignUpVO.getAivSignUpBean().setUserId(naverIfId);
}
// USER_ID 중복 여부 체크
int existsUserIdCnt = aivSignUpService.selectExistsUserId(aivSignUpVO);
// USER_ID 중복이 안 될 경우 USER_NICK_NAME의 중복을 체크하기 위하여 아래 구문을 실행
if(existsUserIdCnt == 0) {
// 사용 불가능한 USER_NICK_NAME 체크
boolean nickChk = StringUtil.checkNickName(naverNickname);
// USER_NICK_NAME이 사용 불가능한 단어가 포함되어 있으면 닉네임_1234(랜덤숫자 4자리를 뒤에 붙임)으로 세팅시켜 줌
if(!nickChk) {
naverNickname = "닉네임_" + decimal4Format.format(Math.random() * 9999);
}
aivSignUpVO.getAivSignUpBean().setUserNickName(naverNickname);
// USER_NICK_NAME의 중복된 값이 있을 경우 반복문을 통하여 랜덤수를 뒤에 부여한 뒤 USER_NICK_NAME을 새로 세팅해 줌
for(int j = 0; j < 10; j++) {
if(j > 0) {
// USER_NICK_NAME이 중복된 경우 랜덤수 두 자리를 뒤에 부여해줌
aivSignUpVO.getAivSignUpBean().setUserNickName(naverNickname + "_" + decimal3Format.format(Math.random() * 999));
}
// USER_NICK_NAME 중복 여부 체크
int existsUserNickNameCnt = aivSignUpService.selectExistsUserNickName(aivSignUpVO);
// USER_NICK_NAME 중복이 안 될 경우 회원정보 저장(회원가입 처리)
if(existsUserNickNameCnt == 0) {
// 기본 데이터 입력(EMP_ID 새로 생성처리)
aivSignUpVO.getAivSignUpBean().setEmpId(aivSignUpVO.getAivSignUpBean().ID_PREFIX + StringUtil.generateKey());
// 회원데이터 저장
cnt = aivSignUpService.insertIFSignUpSave(aivSignUpVO);
break;
}
}
break;
}
}
}
}
if(!emailExists) {
// 로그인처리 로직 시작
}
}