2탄에서 vue의 전체적인 코드를 살펴보았다. vue에서 구현 한 것을 전체적으로 써보자면
네이버 로그인 이미지 버튼 클릭 -> naver 로그인 api 주소 호출 (여기에 클라이언트 아이디와 리다이렉트 주소, 난수를 생성하여 요청을 보냄) -> 네이버 아이디 로그인 후 리다이렉트 주소로 페이지가 이동함 -> 이때 주소의 끝에는 code와 state가 쿼리로 생성되어 있을 것이다. -> 해당 리다이렉트 주소로 오자마자 code랑 state를 가지고 토큰 생성하는 메서드 실행 -> code랑 state formData에 넣어서 axios.post로 백 단에 필요한 정보를 보냄
오늘 마지막으로 할 것은
받아온 fromData 를 이용하여 Access_Token을 발급받고, 그 토큰을 이용하여 유저의 정보를 가져와 파싱 하는 것을 진행해보려고 한다. 이렇게 했을 때 주의 하여 야 할 것은 해당 유저가 이미 DB에 저장되어 있는지 확인해야 하고, 확인 후 저장이 되어 있다면 바로 로그인을 시켜주어야 하고 아니라면 필요한 유저 정보를 빼와서 회원가입 창을 띄어주어야 한다. 또한 가입이 되어 있는데 카카오나 일반회원으로 가입이 되어 있다면 불필요한 중복 회원가입을 하지 않도록 알려주어야 한다.
일단 중복확인까지는 필수사항 이라고 생각해서 코드 구현을 해보려고 한다. 나머지는 입맛에 맞게 각자 원하는 양식에 맞춰 개발하면 될 것 같다!
[Code @Data]
code와 state를 담아줄 @Data 클래스를 하나 만든다.
@Data
public class Code {
private String code;
private String state;
}
[API Controller]
vue의 self.$axios.post('http://localhost:8181/api/naver/login', formData)로 인해 아래의 Controller로 가게 된다.
@PostMapping("/login")
public Map naverToken(Code code) throws JsonProcessingException {
access_token = naverService.loginNaver(code.getCode(), code.getState());
Map map = new HashMap<>();
map.put("access_token", access_token);
map.put("userinfo", naverService.userInfo(access_token));
return map;
}
[NaverTokenVo]
@Service 에 가기 전에 NaverToken을 얻어와서 잠시 저장해 둘 @Data 클래스를 하나 만들어준다.
@Data
public class NaverTokenVo {
private String access_token;
private String refresh_token;
private String token_type;
private int expires_in;
}
[APi Service]
@Service 에서 네이버개발 문서에서 요청 한 대로 작성해서 보내주면 된다.
// 통합 code ,state 받아서 access_token -> 유저 인포도 나옴
public String loginNaver (String code, String state) throws JsonProcessingException {
// 네이버 로그인 Token 발급 API 요청을 위한 header/parameters 설정 부분
RestTemplate token_rt = new RestTemplate(); // REST API 요청용 Template
HttpHeaders naverTokenRequestHeadres = new HttpHeaders(); // Http 요청을 위한 헤더 생성
naverTokenRequestHeadres.add("Content-type", "application/x-www-form-urlencoded"); // application/json 했다가 grant_type missing 오류남 (출력포맷만 json이라는 거엿음)
// 파라미터들을 담아주기위한 맵
MultiValueMap<String, String> params = new LinkedMultiValueMap<>();
params.add("grant_type", "authorization_code");
params.add("client_id", "IiiFJKBOyzL3qvfXasPq");
params.add("client_secret", "PtvyRoMmt_");
params.add("code", code);
params.add("state", state);
HttpEntity<MultiValueMap<String, String>> naverTokenRequest =
new HttpEntity<>(params, naverTokenRequestHeadres);
// 서비스 서버에서 네이버 인증 서버로 요청 전송(POST 또는 GET이라고 공식문서에 있음), 응답은 Json으로 제공됨
ResponseEntity<String> oauthTokenResponse = token_rt.exchange(
"https://nid.naver.com/oauth2.0/token",
HttpMethod.POST,
naverTokenRequest,
String.class
);
// body로 access_token, refresh_token, ;token_type:bearer, expires_in:3600 온 상태
System.out.println(oauthTokenResponse);
// oauthTokenResponse로 받은 토큰정보 객체화
ObjectMapper token_om = new ObjectMapper();
NaverTokenVo naverToken = null;
try {
naverToken = token_om.readValue(oauthTokenResponse.getBody(), NaverTokenVo.class);
} catch (JsonMappingException je) {
je.printStackTrace();
}
// 토큰을 이용해 정보를 받아올 API 요청을 보낼 로직 작성하기
RestTemplate profile_rt = new RestTemplate();
HttpHeaders userDetailReqHeaders = new HttpHeaders();
userDetailReqHeaders.add("Authorization", "Bearer " + naverToken.getAccess_token());
userDetailReqHeaders.add("Content-type", "application/x-www-form-urlencoded;charset=UTF-8");
HttpEntity<MultiValueMap<String, String>> naverProfileRequest = new HttpEntity<>(userDetailReqHeaders);
// 서비스서버 - 네이버 인증서버 : 유저 정보 받아오는 API 요청
ResponseEntity<String> userDetailResponse = profile_rt.exchange(
"https://openapi.naver.com/v1/nid/me",
HttpMethod.POST,
naverProfileRequest,
String.class
);
// 요청 응답 확인
System.out.println("유저인포!!!!!!!!!!!!!!!!" + userDetailResponse);
// 네이버로부터 받은 정보를 객체화
// *이때, 공식문서에는 응답 파라미터에 mobile 밖에없지만, 국제전화 표기로 된 mobile_e164도 같이 옴. 따라서 NaverProfileVo에 mobile_e164 필드도 있어야 정상적으로 객체가 생성됨
ObjectMapper profile_om = new ObjectMapper();
NaverProfileVo naverProfile = null;
try {
naverProfile = profile_om.readValue(userDetailResponse.getBody(), NaverProfileVo.class);
} catch (JsonMappingException je) {
je.printStackTrace();
}
[userInfo]
유저의 정보를 읽어오는 메서드이다.
// 토큰 받아오기
public Map userInfo(String access_token){
Map map = new HashMap<>();
// 토큰을 이용해 정보를 받아올 API 요청을 보낼 로직 작성하기
RestTemplate profile_rt = new RestTemplate();
HttpHeaders userDetailReqHeaders = new HttpHeaders();
userDetailReqHeaders.add("Authorization", "Bearer " + access_token);
userDetailReqHeaders.add("Content-type", "application/x-www-form-urlencoded;charset=UTF-8");
HttpEntity<MultiValueMap<String, String>> naverProfileRequest = new HttpEntity<>(userDetailReqHeaders);
// 서비스서버 - 네이버 인증서버 : 유저 정보 받아오는 API 요청
ResponseEntity<String> userDetailResponse = profile_rt.exchange(
"https://openapi.naver.com/v1/nid/me",
HttpMethod.POST,
naverProfileRequest,
String.class
);
// 요청 응답 확인
System.out.println(userDetailResponse);
// 네이버로부터 받은 정보를 객체화
// *이때, 공식문서에는 응답 파라미터에 mobile 밖에없지만, 국제전화 표기로 된 mobile_e164도 같이 옴. 따라서 NaverProfileVo에 mobile_e164 필드도 있어야 정상적으로 객체가 생성됨
ObjectMapper profile_om = new ObjectMapper();
NaverProfileVo naverProfile = null;
try {
naverProfile = profile_om.readValue(userDetailResponse.getBody(), NaverProfileVo.class);
} catch (JsonProcessingException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
System.out.println("여기봐바>>>>>>>>>>"+naverProfile);
String email = naverProfile.getResponse().getEmail();
System.out.println("이메일!!!!!!!!!" + email);
MemberDto dto = memberservice.getMember(email);
System.out.println("dto!!!!!!!!!" + dto);
if(dto!= null && dto.getId() == 1) {
map.put("message", "동일 아이디로 회원가입 된 카카오 계정이 있습니다.");
}
NaverProfileVo.response naverResponse = naverProfile.getResponse();
map.put("naverResponse", naverResponse);
return map;
}
이제 user 정보까지 모두 가지고 왔다면 나의 DB에 해당 아이디가 있는 것인지 아닌지 확인해야 하는 과정을 거쳐야 한다.
Vue 의 self.$axios.get('http://localhost:8181/members/getSnsMember/' + self.form.email) 요청으로 가게 될 Controller는 아래와 같다.
[Member Controller]
생성해두었던 Member 테이블에 정보가 있는지 훑고 알려주면 된다~
@GetMapping("/getSnsMember/{email}")
public Map get(@PathVariable("email") String email) {
Map map = new HashMap();
boolean flag = false; // 존재하지 않는 회원
MemberDto d = service.getMember(email);
System.out.println(d);
if (d != null) {// dto가 null 이 아니라면
flag = true; // 존재하는 회원
map.put("dto", d);
map.put("flag", flag);
} else {
map.put("messeage", "존재하지 않는 회원이니 회원가입해라");
map.put("flag", flag);
}
System.out.println("flag = " + flag);
return map;
}
그러면 이렇게 네이버 로그인도 끝!!
'프로젝트 > Plan + tiful (플랜티플)' 카테고리의 다른 글
[Rest API] 자바 실제 계좌 예금주 확인 feat. 계좌실명조회 - (2) 최종코드 (0) | 2023.08.02 |
---|---|
[Rest API] 자바 실제 계좌 예금주 확인 feat. 계좌실명조회 - (1) (1) | 2023.07.28 |
[REST API] 네이버 로그인 구현하기 (2) - vue.js (0) | 2023.07.26 |
[Rest Api] 네이버 로그인 구현하기 (1) - vue.js (0) | 2023.07.23 |
[Rest Api] 포트원 API를 이용한 본인인증 구현 (feat. vue.js) - (3) (0) | 2023.07.22 |