ABOUT ME

쉬운거 하나없다

Today
Yesterday
Total
  • [Kakao Login] 카카오 로그인 구현하기 (토큰 / 정보 받아오기 / 회원가입 - 로그인)
    Spring Boot 2024. 1. 18. 15:55
    • 카카오 로그인에서 토큰에서 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> {
    
    }

     

     

Designed by Tistory.