1. 참고 사이트

스프링을 이용한 소셜로그인 구현

 

 

2. 소스코드

2-1. Controller 객체

@Log4j
@AllArgsConstructor
@Controller
public class LoginController {
	private KakaoService kakaoService;

	/*
	* 중략
	*/

	// 카카오 로그인 페이지
	@RequestMapping("/kakao_login")
	public String kakao_login(@RequestParam(value = "code", required = false) String code) throws Exception {
		// HttpSession session = req.getSession();

		System.out.println("#########" + code);
		String access_Token = kakaoService.getAccessToken(code);
		HashMap<String, Object> userInfo = kakaoService.getUserInfo(access_Token);

		System.out.println("###access_Token#### : " + access_Token);
		System.out.println("###userInfo#### : " + userInfo.get("email"));
		System.out.println("###nickname#### : " + userInfo.get("nickname"));
		System.out.println("###profile_image#### : " + userInfo.get("profile_image"));

		// session.setAttribute("user", userInfo.get("nickname"));

		return "log/kakao_access";
	}

	/*
		후략...
	*/
}

 

2-2. Service 객체

public interface KakaoService {
	String getAccessToken(String code);

	HashMap<String, Object> getUserInfo(String access_Token);
}
@Service
public class KakaoServiceImpl implements KakaoService {
	@Override
	public String getAccessToken(String authorize_code) {
		String access_Token = "";
		String refresh_Token = "";
		String reqURL = "https://kauth.kakao.com/oauth/token";

		try {
			URL url = new URL(reqURL);

			HttpURLConnection conn = (HttpURLConnection) url.openConnection();

			// POST 요청을 위해 기본값이 false인 setDoOutput을 true로

			conn.setRequestMethod("POST");
			conn.setDoOutput(true);

			// POST 요청에 필요로 요구하는 파라미터 스트림을 통해 전송
			BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(conn.getOutputStream()));
			StringBuilder sb = new StringBuilder();
			sb.append("grant_type=authorization_code");
			sb.append("&client_id=55fbae94ad6baea8cd340f1850c2a6fe"); // 본인이 발급받은 key
			sb.append("&redirect_uri=http://localhost:8282/ex/kakao_login"); // 본인이 설정해 놓은 경로
			sb.append("&code=" + authorize_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 HashMap<String, Object> getUserInfo(String access_Token) {

		// 요청하는 클라이언트마다 가진 정보가 다를 수 있기에 HashMap타입으로 선언
		HashMap<String, Object> userInfo = new HashMap<>();
		String reqURL = "https://kapi.kakao.com/v2/user/me";
		try {
			URL url = new URL(reqURL);
			HttpURLConnection conn = (HttpURLConnection) url.openConnection();
			conn.setRequestMethod("GET");

			// 요청에 필요한 Header에 포함될 내용
			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 properties = element.getAsJsonObject().get("properties").getAsJsonObject();
			JsonObject kakao_account = element.getAsJsonObject().get("kakao_account").getAsJsonObject();

			String nickname = properties.getAsJsonObject().get("nickname").getAsString();
			String profile_image = properties.getAsJsonObject().get("profile_image").getAsString();
			String email = kakao_account.getAsJsonObject().get("email").getAsString();

			userInfo.put("nickname", nickname);
			userInfo.put("profile_image", profile_image);
			userInfo.put("email", email);

		} catch (IOException e) {
			e.printStackTrace();
		}

		return userInfo;
	}
}

 

2-3. JSP View

...

<div class="flex-c-m">
    <!-- 카카오 로그인 요청 페이지 -->
	<a href="https://kauth.kakao.com/oauth/authorize?
		client_id=55fbae94ad6baea8cd340f1850c2a6fe&
		redirect_uri=http://localhost:8282/ex/kakao_login&
		response_type=code" 
	    class="login100-social-item bg1">
		<img src="<c:url value="/resources/img/kakao_circle.png"/>" width="52" height="52">
	</a>
		
	<a href="#" class="login100-social-item bg2">
		<i class="fa fa-twitter"></i>
	</a>
		
	<a href="#" class="login100-social-item bg3">
		<i class="fa fa-google"></i>
	</a>
</div>

...
<%@ 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>Welcome To Main!</title>
</head>
<body>
	<p>환영합니다.</p>

	<a href="${pageContext.request.contextPath}/board/list">게시판 리스트</a><br>
	<a href="${pageContext.request.contextPath}">로그아웃</a>
</body>
</html>

 

 

3. 구현화면

 

 

4. 미구현사항

  • 로그인이 액세스 되었을때 리다이렉트 부분 해결하기(kakao_access라는 별도의 페이지가 아닌 login.jsp에서만 처리할 것)
  • 로그인된 계정 정보 가져오기(유저의 이름, 닉네임, 이메일 등)
  • 잘못 입력된 유저의 정보를 삭제하는 방법을 카카오 개발자 센터 페이지에서 어떻게 하면 되는지 익히기