JSP
<a href="/member/naver_oauth">
<img class="" src="/resources/include/images/kakao_login_large_wide.png">
</a>
Controller
@RequestMapping(value="/naver_oauth", method=RequestMethod.GET)
public String naverOauth(HttpServletResponse response) {
SecureRandom random = new SecureRandom();
String state = new BigInteger(130, random).toString(32);
// 네이버 로그인 연동 URL 생성
StringBuffer url = new StringBuffer();
url.append("https://nid.naver.com/oauth2.0/authorize?");
url.append("client_id=***본인의 client_id***");
url.append("&response_type=code");
url.append("&redirect_uri=http://localhost:8080/member/naver_login");
// state : 사이트 간 요청 위조(cross-site request forgery) 공격을 방지하기 위해 애플리케이션에서 생성한 상태 토큰값
url.append("&state="+state);
return "redirect:" + url;
}
@RequestMapping(value="/naver_login", method=RequestMethod.GET)
public String naverLogin(@RequestParam(value="code") String code, @RequestParam(value="state") String state, HttpServletRequest request) {
// 토큰 받기
String access_Token = memberService.getNaverToken(code);
// 토큰을 보내서 사용자 정보 받기
MemberVO member = memberService.getNaverInfo(access_Token);
HttpSession session = request.getSession();
session.setAttribute("member", member);
session.setMaxInactiveInterval(-1); // 세션 시간을 무한대로 설정
String prevPage = (String) request.getSession().getAttribute("prevPage");
log.info(prevPage);
if (prevPage != null && !prevPage.equals("")) {
request.getSession().removeAttribute("prevPage");
// 회원가입 - 로그인으로 넘어온 경우 "/"로 redirect
if (prevPage.contains("/member/join")) {
return "redirect:/";
} else {
return "redirect:" + prevPage;
}
} else return "redirect:/";
}
Service / ServiceImpl
// 네이버 토큰 받기
public String getNaverToken(String code);
// 네이버 로그인 정보 저장
public MemberVO getNaverInfo(String access_Token);
// 네이버 토큰
@Override
public String getNaverToken(String code) {
String access_Token = "";
String refresh_Token = "";
String reqURL = "https://nid.naver.com/oauth2.0/token"; // 접근토큰 발급 요청 url
try {
// url 객체 생성
URL url = new URL(reqURL);
// url에서 url connection 객체 얻기
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
// setRequestMethod : HTTP 메소드 설정, 기본값은 GET
conn.setRequestMethod("POST");
// setDoOutput : url connection이 서버에 데이터를 보낼 수 있는지 여부 설정, 기본값 false
conn.setDoOutput(true);
// POST 요청에 필요로 요구하는 파라미터 스트림을 통해 전송
// POST로 보낼 Body 작성
BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(conn.getOutputStream()));
StringBuilder sb = new StringBuilder();
sb.append("grant_type=authorization_code");
sb.append("&client_id=***본인의 client_id***"); // Client ID
sb.append("&client_secret=***본인의 client_secret***"); // Client Secret
sb.append("&code=" + code);
// 버퍼에 있는 값 전부 출력
bw.write(sb.toString());
// 남아있는 데이터를 모두 출력
bw.flush();
// 결과 코드가 200이라면 성공
int responseCode = conn.getResponseCode();
System.out.println("responseCode : " + responseCode);
// 요청을 통해 얻은 JSON 타입의 Response 메세지 읽어오기
BufferedReader br = new BufferedReader(new InputStreamReader(conn.getInputStream()));
String line = "";
String result = "";
while ((line = br.readLine()) != null) {
result += line;
}
System.out.println("response body : " + result);
// Gson 라이브러리에 포함된 클래스로 JSON파싱 객체 생성
JsonParser parser = new JsonParser();
JsonElement element = parser.parse(result);
access_Token = element.getAsJsonObject().get("access_token").getAsString();
refresh_Token = element.getAsJsonObject().get("refresh_token").getAsString();
System.out.println("access_token : " + access_Token);
System.out.println("refresh_token : " + refresh_Token);
br.close();
bw.close();
} catch (IOException e) {
e.printStackTrace();
}
return access_Token;
}
@Override
public MemberVO getNaverInfo(String access_Token) {
HashMap<String, Object> userInfo = new HashMap<String, Object>();
String reqURL = "https://openapi.naver.com/v1/nid/me";
try {
URL url = new URL(reqURL);
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
conn.setRequestMethod("POST");
conn.setRequestProperty("Authorization", "Bearer " + access_Token);
int responseCode = conn.getResponseCode();
System.out.println("responseCode : " + responseCode);
BufferedReader br = new BufferedReader(new InputStreamReader(conn.getInputStream()));
String line = "";
String result = "";
while ((line = br.readLine()) != null) {
result += line;
}
System.out.println("response body : " + result);
JsonParser parser = new JsonParser();
JsonElement element = parser.parse(result);
JsonObject response = element.getAsJsonObject().get("response").getAsJsonObject();
String user_id = response.getAsJsonObject().get("id").getAsString();
String name = response.getAsJsonObject().get("name").getAsString();
String email = response.getAsJsonObject().get("email").getAsString();
userInfo.put("user_id", user_id);
userInfo.put("user_name", name);
userInfo.put("email", email);
} catch (IOException e) {
e.printStackTrace();
}
// 회원 정보가 있는지 확인
MemberVO result = memberDao.findNaver(userInfo);
// 회원 정보 없을 때
if(result == null) {
memberDao.naverInsert(userInfo);
return memberDao.findNaver(userInfo);
} else {
return result; // 회원 정보 있으면 회원 정보 리턴
}
}
DAO
// 네이버 정보 확인
public MemberVO findNaver(HashMap<String, Object> userInfo);
// 네이버 정보 저장
public void naverInsert(HashMap<String, Object> userInfo);
Mapper
<!-- 네이버 회원 정보 찾기 -->
<select id="findNaver" parameterType="java.util.HashMap" resultType="member">
<![CDATA[
select *
from member
where user_id = #{user_id} and user_name=#{user_name} and email=#{email}
]]>
</select>
<!-- 네이버 회원 정보 저장 -->
<insert id="naverInsert" parameterType="java.util.HashMap">
INSERT INTO member(user_id, user_name, email)
VALUES (#{user_id}, #{user_name}, #{email})
</insert>
'프로젝트 > JAM' 카테고리의 다른 글
---- (0) | 2024.02.05 |
---|---|
-- (0) | 2023.12.04 |
[SpringMVC] Spring Security + JWT토큰 (1) | 2023.10.03 |
[Spring] Spring Security (0) | 2023.09.02 |
[Spring] 카카오 소셜 로그인 구현 REST API (0) | 2023.08.21 |