Spring Boot
[Naver Login] 네이버 로그인 구현하기 (토큰 & 회원정보 담아오기 / 로그아웃)
어코링
2024. 1. 24. 14:42
1. LoginController
private NaverAPI naver;
@GetMapping("/nlogin")
public String nlogin(@RequestParam("code") String code, Model model, HttpSession session) {
System.out.println(code);
String access_token = naver.getAccessToken(code);
try {
User userInfo = naver.getUserInfo(access_token).orElse(null);
System.out.println("*****************"+userInfo);
if (userInfo != null) {
session.setAttribute("loginUser", userInfo);
return "redirect:/home";
} else {
return "redirect:/social/loginPage";
}
} catch (Exception e) {
return "redirect:/social/loginPage";
}
}
@GetMapping(value="/logout")
public String logout(HttpSession session) {
session.invalidate();
return "redirect:/home";
}
네이버로그인과 로그아웃
네이버로그인
HttpSession session안에 NaverAPI Service로 불러온 naver 인스턴스 안에 로그인시 받아온 Token을 저장하고,
저장된 Token이 null이면 session에 LoginInfo를 넣어준다. 그리고 home.jsp 로 이동.
그렇지 않으면 그냥 loginPage.jsp 남아있는다.
로그아웃
session.invalidate(); -> 로 session 초기화로 logininfo 없애서 logout을 진행시킨다.
2. home.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%@taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>
<c:if test="${not empty sessionScope.loginUser}">
${sessionScope.loginUser.username}님 안녕하세요.
<br/>
<a href="social/logout">로그아웃</a>
<a>게시판가기</a>
</c:if>
<c:if test="${empty sessionScope.loginUser}">
<a href="social/loginPage">로그인</a>
</c:if>
</body>
</html>
3. NaverAPI
package com.se.social.service;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.UnsupportedEncodingException;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URISyntaxException;
import java.net.URL;
import java.net.URLEncoder;
import java.util.Optional;
import org.springframework.stereotype.Service;
import com.se.social.domain.OauthId;
import com.se.social.entity.User;
import com.se.social.repository.UserRepository;
import lombok.RequiredArgsConstructor;
import lombok.extern.log4j.Log4j2;
import com.google.gson.JsonElement;
import com.google.gson.JsonObject;
import com.google.gson.JsonParser;
@Log4j2
@Service
@RequiredArgsConstructor
public class NaverAPI {
private final UserRepository repository;
public String getAccessToken(String code) {
try {
String redirectURI = URLEncoder.encode("http://localhost:8080/social/nlogin", "UTF-8");
String apiURL;
apiURL = "https://nid.naver.com/oauth2.0/token?grant_type=authorization_code&";
apiURL += "client_id=" + "***client_id***";
apiURL += "&client_secret=" + "***client_secret***";
apiURL += "&redirect_uri=" + "http://localhost:8080/social/nlogin";
apiURL += "&code=" + code;
apiURL += "&state=" + 1234; // 임의의 값
String access_token = "";
String refresh_token = "";
System.out.println("apiURL=" + apiURL);
URL url = new URL(apiURL);
HttpURLConnection con = (HttpURLConnection) url.openConnection();
con.setRequestMethod("POST");
int responseCode = con.getResponseCode();
BufferedReader br;
System.out.print("responseCode=" + responseCode);
if (responseCode == 200) { // 정상 호출
br = new BufferedReader(new InputStreamReader(con.getInputStream()));
} else { // 에러 발생
br = new BufferedReader(new InputStreamReader(con.getErrorStream()));
return null;
}
String inputLine;
StringBuffer res = new StringBuffer();
while ((inputLine = br.readLine()) != null) {
res.append(inputLine);
}
if (responseCode == 200) {
System.out.println(res.toString());
}
String result = res.toString(); // 변경: 읽은 내용을 String으로 변환
System.out.println("response body : " + result);
JsonParser parser = new JsonParser();
JsonElement element = parser.parse(result);
br.close();
return element.getAsJsonObject().get("access_token").getAsString();
} catch (Exception e) {
System.out.println(e);
return null;
}
}
// getUserInfo
public Optional<User> getUserInfo(String accessToken) throws IOException {
// 네이버 로그인 접근 토큰;
String apiURL = "https://openapi.naver.com/v1/nid/me";
String headerStr = "Bearer " + accessToken; // Bearer 다음에 공백 추가
String result = requestToServer(apiURL, headerStr);
System.out.println("사용자 정보 " + result);
JsonParser parser = new JsonParser();
JsonElement element = parser.parse(result);
JsonObject response = element.getAsJsonObject().get("response").getAsJsonObject();
System.out.println("*****response: " + response);
String token_id = response.getAsJsonObject().get("id").getAsString();
String nickname = response.getAsJsonObject().get("name").getAsString();
String email = response.getAsJsonObject().get("email").getAsString();
System.out.println("email" + email);
Optional<User> opt_user = repository.findById(new OauthId("naver", token_id));
System.out.println("--------opt_user : " + opt_user);
User user = new User();
if (opt_user.isPresent()) {
return opt_user;
}else {
user.setUseremail(email);
user.setUsername(nickname);
user.setOauthtype("naver");
user.setOauthtoken(token_id);
repository.save(user);
return Optional.of(user);
}
}
private String requestToServer(String apiURL, String headerStr) throws IOException {
URL url = new URL(apiURL);
HttpURLConnection con = (HttpURLConnection) url.openConnection();
con.setRequestMethod("GET");
System.out.println("header Str: " + headerStr);
if (headerStr != null && !headerStr.equals("")) {
con.setRequestProperty("Authorization", headerStr);
}
int responseCode = con.getResponseCode();
BufferedReader br;
System.out.println("responseCode=" + responseCode);
if (responseCode == 200) { // 정상 호출
br = new BufferedReader(new InputStreamReader(con.getInputStream()));
} else { // 에러 발생
br = new BufferedReader(new InputStreamReader(con.getErrorStream()));
}
String inputLine;
StringBuffer res = new StringBuffer();
while ((inputLine = br.readLine()) != null) {
res.append(inputLine);
}
br.close();
if (responseCode == 200) {
return res.toString();
} else {
return null;
}
}
}
결과