본문 바로가기

카테고리 없음

Bank App 만들기 ( deployment ) - Bank 카카오 소셜 로그인 처리

Auth 2.0 
1. 내 애플리케이션 항목에 등록 
(로그인) - (kakao developers내 애플리케이션 등록) 
2. 플랫폼(web 선택) - 사이트 도메인 기본설정 
- http://localhost:8080
3. 카카오 로그인 사용 시 Redirect URI를 등록
- 활성화 ON 처리 
- http://localhost:8080/user/kakao (리다이렉트 URI 설정) 
4. 동의 항목 설정(제품설정--동의항목 왼쪽 메뉴)
- 닉네임, 프로필 사진
5. 리소스 다운로드 
- 도구 --> 리소스다운로드 --> 카카오로그인 
6. REST API 키 
- 21625653d6c77548fa54d359f8707123

------------------------------------------
7. 인가 코드 받기 
https://kauth.kakao.com/oauth/authorize?response_type=code&client_id=21625653d6c77548fa54d359f8707123&redirect_uri=http://localhost:8080/user/kakao
7-1 . 
콜백 메서드 구현 (UserController) 


8. 토큰 받기 
POST  
https://kauth.kakao.com/oauth/token

응답 결과 
{"access_token":"sPO9F068CFZ6quHypfkp-RNC81o3lbQ5AAAAAQo8I-cAAAGRWKPXPcwhKCpFsUJR","token_type":"bearer","refresh_token":"MQ1Q4-JSV9GU_A0LOLIrsD2RUgd0BwfgAAAAAgo8I-cAAAGRWKPXOswhKCpFsUJR","expires_in":21599,"scope":"profile_image profile_nickname","refresh_token_expires_in":5183999}
- DTO JSON 파싱 처리 완료 

9. 사용자 정보 가져오기 
GET/POST
https://kapi.kakao.com/v2/user/me
인증방식 
- 만들었던 OAuthToken.getAccessToken(); 

https://kapi.kakao.com/v2/user/me?secure_resource=true

 

 

 

 

UserController 코드 추가
	@GetMapping("/kakao")
	// @ResponseBody // @RestControler = @Controller + @ResposeBody 
	public String getMethodName(@RequestParam(name = "code") String code) {
		System.out.println("code : " + code);
		
		// POST - 카카오 토큰 요청 받기 
		// Header, body 구성 
		RestTemplate rt1 = new RestTemplate();
		// 헤더 구성 
		HttpHeaders header1 = new HttpHeaders();
		header1.add("Content-type", "application/x-www-form-urlencoded;charset=utf-8");
		// 바디 구성 
		MultiValueMap<String, String> params1 = new LinkedMultiValueMap<String, String>();
		params1.add("grant_type", "authorization_code");
		params1.add("client_id", "21625653d6c77548fa54d359f8707123");
		params1.add("redirect_uri", "http://localhost:8080/user/kakao");
		params1.add("code", code);
		
		// 헤더 + 바디 결합 
		HttpEntity<MultiValueMap<String, String>> reqkakoMessage 
			= new HttpEntity<>(params1, header1);  
			
		// 통신 요청 
	    ResponseEntity<OAuthToken> response1	=  rt1.exchange("https://kauth.kakao.com/oauth/token", 
				HttpMethod.POST, reqkakoMessage, OAuthToken.class);
	    System.out.println("response : " + response1.getBody().toString());
	    
	    // 카카오 리소스서버 사용자 정보 가져오기 
	    RestTemplate rt2 = new RestTemplate();
	    // 헤더 
	    HttpHeaders headers2 = new HttpHeaders();
	    // 반드시 Bearer 값 다음에 공백 한칸 추가 !! 
	    headers2.add("Authorization", "Bearer " +response1.getBody().getAccessToken());
	    headers2.add("Content-type", "application/x-www-form-urlencoded;charset=utf-8");
	    // 본문 x 
	    
	    // HTTP Entity 만들기 
	    HttpEntity<MultiValueMap<String, String>> reqKakoInfoMessage = new HttpEntity<>(headers2);
	    
	    // 통신 요청 
	    ResponseEntity<KakaoProfile> resposne2 = 
	    			rt2.exchange("https://kapi.kakao.com/v2/user/me", HttpMethod.POST, 
	    			reqKakoInfoMessage, KakaoProfile.class);
	    
	    KakaoProfile kakaoProfile = resposne2.getBody();
	    // ---- 카카오 사용자 정보 응답 완료 ----------
	    
	    // 최초 사용자라면 자동 회원 가입 처리 (우리 서버) 
	    // 회원가입 이력이 있는 사용자라면 바로 세션 처리 (우리 서버) 
	    // 사전기반 --> 소셜 사용자는 비밀번호를 입력하는가? 안하는가? 
	    // 우리서버에 회원가입시에 --> password -> not null (무건 만들어 넣어야 함 DB 정책) 
	    
	    // 1.회원가입 데이터 생성 
	    SignUpDTO signUpDTO = SignUpDTO.builder()
	    		.username(kakaoProfile.getProperties().getNickname() 
	    				+ "_" + kakaoProfile.getId())
	    		.fullname("OAuth_" + kakaoProfile.getProperties().getNickname())
	    		.password(tencoKey)
	    		.build();
	   
	    // 2.우리사이트 최초 소셜 사용자 인지 판별 
	    User oldUser = userService.searchUsername(signUpDTO.getUsername());
	    // select * from user_tb where username = ?
	    if(oldUser == null) {
	    	// 사용자가 최초 소셜 로그인 사용자 임
	    	oldUser = new User();
	    	oldUser.setUsername(signUpDTO.getUsername());
	    	oldUser.setPassword(null);
	    	oldUser.setFullname(signUpDTO.getFullname());
	    	userService.createUser(signUpDTO);
	    }
	    
	    // 프로필 이미지 여부에 따라 조건식 추가 
    	signUpDTO.setOriginFileName(kakaoProfile.getProperties().getThumbnailImage());
    	oldUser.setUploadFileName(kakaoProfile.getProperties().getThumbnailImage());
	    
	    // 자동 로그인 처리
	    session.setAttribute(Define.PRINCIPAL, oldUser);
		return "redirect:/account/list";
	}

 

 

 

 

 

OAuthToken 코드 생성
package com.tenco.bank.dto;

import com.fasterxml.jackson.databind.PropertyNamingStrategies;
import com.fasterxml.jackson.databind.annotation.JsonNaming;

import lombok.Data;
import lombok.ToString;

// JSON 형식에 코딩 컨벤션이 스네이크 케이스를 카멜 노테이션으로 할당하라! 
@JsonNaming(value = PropertyNamingStrategies.SnakeCaseStrategy.class)
@Data
@ToString
public class OAuthToken {

    private String accessToken;
    private String tokenType;
    private String refreshToken;
    private Integer expiresIn;
    private String scope;
    private Integer refreshTokenExpiresIn;
	
}

 

 

 

 

yml 추가
# 초기 파라메터 설정 
file:
  upload-dir: C:\\work_spring\\upload/

tenco:
  key: 54d5cb2d332dbdb4850293caae4559ce88b65163f1ea5d4e4b3ac49d772ded14

 

 

 

 

@Controller  
@RequestMapping("/user")  
@RequiredArgsConstructor
public class UserController {
	
	@Autowired
	private final UserService userService;
	private final HttpSession session;
	
	@Value("${tenco.key}")
	private String tencoKey; 
	
	// ... 생략

 

 

 

 

KakaoProfile 코드 추가
package com.tenco.bank.dto;

import com.fasterxml.jackson.databind.PropertyNamingStrategies;
import com.fasterxml.jackson.databind.annotation.JsonNaming;

import lombok.Data;
import lombok.ToString;

@JsonNaming(value = PropertyNamingStrategies.SnakeCaseStrategy.class)
@Data
@ToString
public class KakaoProfile {
	private Long id; 
	private String connectedAt; 
	private Properties properties;
}

 

 

 

 

UserService 코드 추가
	/**
	 * username 사용자 존재 여부 조회 
	 * @param String username 
	 * @return User, null 
	 */
	public User searchUsername(String username) {
		return userRepository.findByUsername(username);
	}
728x90