- 카카오 로그인에서 토큰에서 id 값 받아오기
- 불러온 id값으로 oauthtype, oauthtoken 을 복합키로 구성함.
- 중복 검사 (Optional<User>로 검사하여 만약 중복된 OauthId 객체가 있을 경우 로그인 하게 됨. 없으면 회원가입과 로그인 동시에 하는 것임.)
- import 잘못해서 고생좀 했음 ;; import 할 때 어디서 import 되는지 잘 보고 하도록
KakaoAPI
package com.se.social.service;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.Optional;
import org.springframework.stereotype.Service;
import com.google.gson.JsonElement;
import com.google.gson.JsonObject;
import com.google.gson.JsonParser;
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;
@Log4j2
@Service
@RequiredArgsConstructor
public class KakaoAPI {
private final UserRepository repository;
// getToken
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=--------------");
sb.append("&redirect_uri=http://localhost:8080/social/login");
sb.append("&code=" + authorize_code);
sb.append("&client_secret=--------------");
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;
} // getAccessToken
// getUserInfo
public String getUserInfo(String access_token) {
String reqUrl = "https://kapi.kakao.com/v2/user/me";
try{
URL url = new URL(reqUrl);
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
conn.setRequestMethod("POST");
// 요청에 필요한 Header에 포함될 내용
conn.setRequestProperty("Authorization", "Bearer " + access_token);
//conn.setRequestProperty("Content-type", "application/x-www-form-urlencoded;charset=utf-8");
int responseCode = conn.getResponseCode();
log.info("[KakaoApi.getUserInfo] responseCode : {}", responseCode);
BufferedReader br;
if (responseCode >= 200 && responseCode <= 300) {
br = new BufferedReader(new InputStreamReader(conn.getInputStream()));
} else {
br = new BufferedReader(new InputStreamReader(conn.getErrorStream()));
}
String line = "";
StringBuilder responseSb = new StringBuilder();
while((line = br.readLine()) != null){
responseSb.append(line);
}
String result = responseSb.toString();
log.info("responseBody = {}", 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 email = kakao_account.getAsJsonObject().get("email").getAsString();
String token_id = element.getAsJsonObject().get("id").getAsString();
Optional<User> opt_user = repository.findById(new OauthId("kakao", token_id));
if (!opt_user.isPresent()) {
User user = new User();
user.setUseremail(email);
user.setUsername(nickname);
user.setOauthtype("kakao");
user.setOauthtoken(token_id);
System.out.println("user!!!!!!!" + user);
repository.save(user);
}
br.close();
return "success";
}catch (Exception e){
e.printStackTrace();
return "fail";
}
} // getUserInfo
}
OauthId (복합키 설정)
package com.se.social.domain;
import java.io.Serializable;
import javax.persistence.IdClass;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
@Data
@Builder
@AllArgsConstructor
@NoArgsConstructor
public class OauthId implements Serializable {
private static final long serialVersionUID = 1L; // 기본값(초기화)
private String oauthtype;
private String oauthtoken;
}
LoginController
package com.se.social.controller;
import java.util.Map;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import com.se.social.service.KakaoAPI;
import lombok.AllArgsConstructor;
import lombok.extern.log4j.Log4j2;
@Log4j2
@AllArgsConstructor
@RequestMapping(value = "/social")
@Controller
public class LoginController {
private KakaoAPI kakao;
@GetMapping("loginpage")
public void getLogin() {
}
@GetMapping("/login")
public String login(@RequestParam("code") String code) {
System.out.println(code);
String access_token = kakao.getAccessToken(code);
System.out.println("controller access_token : " + access_token);
if(kakao.getUserInfo(access_token).equals("success")) {
return "redirect:/home";
} else {
return "redirect:/social/loginPage";
}
}
}
User
package com.se.social.entity;
import java.io.Serializable;
import javax.persistence.Entity;
import javax.persistence.Id;
import javax.persistence.IdClass;
import javax.persistence.Table;
import javax.persistence.Transient;
import com.se.social.domain.OauthId;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
@Entity
@Table
@Data
@AllArgsConstructor
@NoArgsConstructor
@IdClass(OauthId.class)
public class User implements Serializable {
@Transient
private static final long serialVersionUID = 1L;
private String username;
@Id
private String oauthtype;
@Id
private String oauthtoken;
private String useremail;
}
UserRepository
package com.cm.personalProject.repository;
import org.springframework.data.jpa.repository.JpaRepository;
import com.cm.personalProject.domain.OauthId;
import com.cm.personalProject.entity.User;
public interface UserRepository extends JpaRepository<User, OauthId> {
}