💡 학습목표
액세트 토큰으로 자원 서버에 정보 요청
package com.tencoding.bank.dto;
import com.fasterxml.jackson.databind.PropertyNamingStrategies;
import com.fasterxml.jackson.databind.annotation.JsonNaming;
import lombok.Data;
@Data
@JsonNaming(value = PropertyNamingStrategies.SnakeCaseStrategy.class)
public class AuthToken {
private String accessToken;
private String tokenType;
private String refreshToken;
private String scope;
private Integer expiresIn;
}
package com.tencoding.bank.controller;
import javax.servlet.http.HttpSession;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpMethod;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Controller;
import org.springframework.util.LinkedMultiValueMap;
import org.springframework.util.MultiValueMap;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.client.RestTemplate;
import com.tencoding.bank.dto.AuthToken;
import com.tencoding.bank.dto.KakaoProfile;
import com.tencoding.bank.dto.SignInFormDto;
import com.tencoding.bank.dto.SignUpFormDto;
import com.tencoding.bank.handler.exception.CustomRestfulException;
import com.tencoding.bank.repository.model.User;
import com.tencoding.bank.service.UserService;
import com.tencoding.bank.util.Define;
@Controller
@RequestMapping({"/user","/"})
public class UserController {
@Value("${tenco.key}")
private String tencoKey;
@Autowired
private UserService userService;
@Autowired
private HttpSession session;
@GetMapping("/sign-up")
public String signUp() {
return "user/signUp";
}
@GetMapping({"/sign-in","/"})
public String signIn() {
return "user/signIn";
}
@PostMapping("/sign-up")
public String signUpProc(SignUpFormDto signUpFormDto) {
if(signUpFormDto.getUsername() == null
|| signUpFormDto.getUsername().isEmpty()) {
throw new CustomRestfulException("username을 입력하세요", HttpStatus.BAD_REQUEST);
}
if(signUpFormDto.getPassword() == null
|| signUpFormDto.getPassword().isEmpty()) {
throw new CustomRestfulException("password을 입력하세요", HttpStatus.BAD_REQUEST);
}
if(signUpFormDto.getFullname() == null
|| signUpFormDto.getFullname().isEmpty()) {
throw new CustomRestfulException("fullname을 입력하세요", HttpStatus.BAD_REQUEST);
}
userService.signUp(signUpFormDto);
return "redirect:/user/sign-in";
}
@PostMapping("/sign-in")
public String signInProc(SignInFormDto signInFormDto) {
if(signInFormDto.getUsername() == null
|| signInFormDto.getUsername().isEmpty()) {
throw new CustomRestfulException("username을 입력하세요", HttpStatus.BAD_REQUEST);
}
if(signInFormDto.getPassword() == null
|| signInFormDto.getPassword().isEmpty()) {
throw new CustomRestfulException("password을 입력하세요", HttpStatus.BAD_REQUEST);
}
User principal = userService.signIn(signInFormDto);
principal.setPassword(null);
session.setAttribute(Define.PRINCIPAL, principal);
return "redirect:/account/list";
}
@GetMapping("/logout")
public String logout() {
session.invalidate();
return "redirect:/user/sign-in";
}
@GetMapping("/kakao/callback")
public String kakaoCallBack(@RequestParam String code) {
System.out.println("메서드 동작");
RestTemplate rt = new RestTemplate();
HttpHeaders headers = new HttpHeaders();
headers.add("Content-type", "application/x-www-form-urlencoded;charset=utf-8");
MultiValueMap<String, String> params = new LinkedMultiValueMap<>();
params.add("grant_type", "authorization_code");
params.add("client_id", "eceda66395de20a268098856518bee51");
params.add("redirect_uri", "http://localhost/user/kakao/callback");
params.add("code", code);
HttpEntity<MultiValueMap<String, String>> reqMes
= new HttpEntity<>(params, headers);
ResponseEntity<AuthToken> response = rt.exchange("https://kauth.kakao.com/oauth/token",
HttpMethod.POST, reqMes, AuthToken.class);
System.out.println("카카오 토큰 확인 : "+ response.getBody());
RestTemplate rt2 = new RestTemplate();
HttpHeaders headers2 = new HttpHeaders();
headers2.add("Authorization", "Bearer "+response.getBody().getAccessToken());
headers2.add("Content-type", "application/x-www-form-urlencoded;charset=utf-8");
HttpEntity<MultiValueMap<String, String>> kakaoInfo
= new HttpEntity<>(headers2);
ResponseEntity<KakaoProfile> response2 = rt2.exchange("https://kapi.kakao.com/v2/user/me",
HttpMethod.POST, kakaoInfo, KakaoProfile.class);
System.out.println("-----------------------------------");
System.out.println(response2.getBody().getKakaoAccount().getEmail());
System.out.println(response2.getBody().getKakaoAccount().getProfile().getNickname());
System.out.println("-----------카카오 서버 정보 받기 완료-----------");
KakaoProfile kakaoProfile = response2.getBody();
SignUpFormDto signUpFormDto = SignUpFormDto
.builder()
.username(kakaoProfile.getKakaoAccount().getEmail()+"_"+kakaoProfile.getId())
.fullname("Auth_"+kakaoProfile.getKakaoAccount().getEmail())
.password(tencoKey)
.build();
System.out.println(tencoKey);
User oldUser = userService.searchUserName(signUpFormDto.getUsername());
if(oldUser == null) {
userService.signUp(signUpFormDto);
oldUser.setUsername(signUpFormDto.getUsername());
oldUser.setFullname(signUpFormDto.getFullname());
}
oldUser.setPassword(null);
session.setAttribute(Define.PRINCIPAL, oldUser);
return "redirect:/account/list";
}
}
package com.tencoding.bank.dto;
import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.annotation.JsonProperty;
import com.fasterxml.jackson.annotation.JsonPropertyOrder;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
public class KakaoProfile {
@JsonProperty("id")
private Long id;
@JsonProperty("connected_at")
private String connectedAt;
@JsonProperty("properties")
private Properties properties;
@JsonProperty("kakao_account")
private KakaoAccount kakaoAccount;
@JsonInclude(JsonInclude.Include.NON_NULL)
@JsonPropertyOrder({ "nickname" })
@Data
public class Properties {
@JsonProperty("nickname")
private String nickname;
}
@JsonInclude(JsonInclude.Include.NON_NULL)
@JsonPropertyOrder({ "profile_nickname_needs_agreement", "profile", "has_email", "email_needs_agreement",
"is_email_valid", "is_email_verified", "email" })
@Data
public class KakaoAccount {
@JsonProperty("profile_nickname_needs_agreement")
private Boolean profileNicknameNeedsAgreement;
@JsonProperty("profile")
private Profile profile;
@JsonProperty("has_email")
private Boolean hasEmail;
@JsonProperty("email_needs_agreement")
private Boolean emailNeedsAgreement;
@JsonProperty("is_email_valid")
private Boolean isEmailValid;
@JsonProperty("is_email_verified")
private Boolean isEmailVerified;
@JsonProperty("email")
private String email;
@JsonInclude(JsonInclude.Include.NON_NULL)
@JsonPropertyOrder({
"nickname"
})
@Data
public class Profile {
@JsonProperty("nickname")
private String nickname;
}
}
}
public User searchUsername(String username) {
return userRepository.findByUsername(username);
}