카카오로 로그인하기:
https://developers.kakao.com/console/app
카카오계정 로그인
여기를 눌러 링크를 확인하세요.
accounts.kakao.com
애플리케이션 추가하기
플랫폼 등록
사이트 주소, 콜백 주소 설정(https://localhost:8080 , https://localhost:8080/user/kakao/callback)
동의항목 설정
REST API 키 복사
프론트엔드에서 onclick="location.href='https://kauth.kakao.com/oauth/authorize?client_id={내 rest api 키}&redirect_uri={콜백주소}&response_type=code'" 로 버튼생성
controller:
@GetMapping("/user/kakao/callback")
public ResponseDto<?> kakaoLogin(@RequestParam String code, HttpServletResponse response){
return memberService.kakaoLogin(code, response);
}
@RequestParam에 String code로 받는다.
Service:
public ResponseDto<?> kakaoLogin(String code, HttpServletResponse response) {
try {
// 1. "인가 코드"로 "액세스 토큰" 요청
String accessToken = getKakaoAccessToken(code);
// 2. 토큰으로 카카오 API 호출
KakoUserInfoDto kakaoUserInfo = getKakaoUserInfo(accessToken);
// DB 에 중복된 Kakao Id 가 있는지 확인
Long kakaoId = kakaoUserInfo.getId();
Member kakaoUser = memberRepository.findByKakaoId(kakaoId)
.orElse(null);
if(kakaoUser != null){
TokenDto tokenDto = tokenProvider.generateTokenDto(kakaoUser);
tokenToHeaders(tokenDto, response);
return ResponseDto.success(
MemberResponseDto.builder()
.id(kakaoUser.getId())
.username(kakaoUser.getUsername())
.nickname(kakaoUser.getNickname())
.createdAt(kakaoUser.getCreatedAt())
.modifiedAt(kakaoUser.getModifiedAt())
.build()
);
}
else{
// 회원가입
Member member = Member.builder()
.username(UUID.randomUUID().toString())
.nickname(kakaoUserInfo.getNickname())
.password(passwordEncoder.encode(UUID.randomUUID().toString()))
.kakaoId(kakaoId)
.build();
memberRepository.save(member);
TokenDto tokenDto = tokenProvider.generateTokenDto(member);
tokenToHeaders(tokenDto, response);
return ResponseDto.success(
MemberResponseDto.builder()
.id(member.getId())
.username(member.getUsername())
.nickname(member.getNickname())
.createdAt(member.getCreatedAt())
.modifiedAt(member.getModifiedAt())
.build()
);
}
}
catch (JsonProcessingException e){
return ResponseDto.fail("403","로그인에 실패했습니다.");
}
}
1. 인가코드로 엑세스 토큰 요청하기
2. 엑세스 토큰으로 사용자 정보 요청하기
3. 사용자정보 활용하기
로 구성된다.
멤버테이블에 카카오로 가입된 계정을 구분하기 위해 카카오아이디(고유번호)를 가져와 kakaoId에 저장하고 일반 로그인 시 kakaoId가 null인 경우에만 로그인이 되도록 함.
해당 kakaoId가 이미 테이블에 존재하면 토큰을 생성 후 로그인 처리,
해당 kakaoId가 존재하지 않으면 UUID로 아이디와 패스워드에 랜덤값을 준 뒤 닉네임, kakaoId와 함께 멤버 테이블에 저장 후 토큰 발급+로그인
인가코드로 엑세스 토큰 요청하기:
private String getKakaoAccessToken(String code) throws JsonProcessingException {
// HTTP Header 생성
HttpHeaders headers = new HttpHeaders();
headers.add("Content-type", "application/x-www-form-urlencoded;charset=utf-8");
// HTTP Body 생성
MultiValueMap<String, String> body = new LinkedMultiValueMap<>();
body.add("grant_type", "authorization_code");
body.add("client_id", "2b986d1b574416a7d6d064619545aaff");//내 api키
body.add("redirect_uri", "http://localhost:8080/user/kakao/callback");
body.add("code", code);//카카오로부터 받은 인가코드
// HTTP 요청 보내기
HttpEntity<MultiValueMap<String, String>> kakaoTokenRequest =
new HttpEntity<>(body, headers);//httpentity객체를 만들어서 보냄
RestTemplate rt = new RestTemplate();//서버 대 서버 요청을 보냄
ResponseEntity<String> response = rt.exchange(
"https://kauth.kakao.com/oauth/token",
HttpMethod.POST,
kakaoTokenRequest,
String.class
);//리스폰스 받기
// HTTP 응답 (JSON) -> 액세스 토큰 파싱
String responseBody = response.getBody();//바디부분
ObjectMapper objectMapper = new ObjectMapper();
JsonNode jsonNode = objectMapper.readTree(responseBody);//json형태를 객체형태로 바꾸기
return jsonNode.get("access_token").asText();
}
objectMapper.readTree는 JsonProcessingException을 throw해야 함
토큰으로 사용자 정보 가져오기:
private KakoUserInfoDto getKakaoUserInfo(String accessToken) throws JsonProcessingException {
// HTTP Header 생성
HttpHeaders headers = new HttpHeaders();
headers.add("Authorization", "Bearer " + accessToken);
headers.add("Content-type", "application/x-www-form-urlencoded;charset=utf-8");
// HTTP 요청 보내기
HttpEntity<MultiValueMap<String, String>> kakaoUserInfoRequest = new HttpEntity<>(headers);
RestTemplate rt = new RestTemplate();//서버 대 서버 요청을 보냄
ResponseEntity<String> response = rt.exchange(
"https://kapi.kakao.com/v2/user/me",
HttpMethod.POST,
kakaoUserInfoRequest,
String.class
);
String responseBody = response.getBody();
ObjectMapper objectMapper = new ObjectMapper();
JsonNode jsonNode = objectMapper.readTree(responseBody);
Long id = jsonNode.get("id").asLong();
String nickname = jsonNode.get("properties")
.get("nickname").asText();
return new KakoUserInfoDto(id,nickname);
}
정보를 담을 KakaoInfoDto를 만든다.
리퀘스트로 받은 jsonNode에서 필요한 정보를 가져온다.
jsonNode 구조 예시:
{
"id": 1632335751,
"properties": {
"nickname": "르탄이",
"profile_image": "http://k.kakaocdn.net/...jpg",
"thumbnail_image": "http://k.kakaocdn.net/...jpg"
},
"kakao_account": {
"profile_needs_agreement": false,
"profile": {
"nickname": "르탄이",
"thumbnail_image_url": "http://k.kakaocdn.net/...jpg",
"profile_image_url": "http://k.kakaocdn.net/...jpg"
},
"has_email": true,
"email_needs_agreement": false,
"is_email_valid": true,
"is_email_verified": true,
"email": "letan@sparta.com"
}
}
더 자세한 내용: https://developers.kakao.com/docs/latest/ko/kakaologin/common
Kakao Developers
카카오 API를 활용하여 다양한 어플리케이션을 개발해보세요. 카카오 로그인, 메시지 보내기, 친구 API, 인공지능 API 등을 제공합니다.
developers.kakao.com
깃 포크, 풀 리퀘스트 활용해보기:
1. 가져올 깃 프로젝트에서 상단 우측 fork눌러서 내 리포지토리에 복사
2. 새 브랜치 생성 후 메인 브랜치 내용 복사
3. 메인 브랜치는 싱크만 하고 새 브랜치에서 작업
4. 메인브랜치 싱크 후 새브랜치와 병합하며 conflict 처리
5. full request전달
6. 메인 깃 프로젝트 소유자가 전달된 full request확인 후 merge
'TIL' 카테고리의 다른 글
2022.08.16.TIL (0) | 2022.08.16 |
---|---|
2022.08.15.TIL (0) | 2022.08.15 |
2022.08.11.TIL (0) | 2022.08.11 |
2022.08.09.TIL (0) | 2022.08.09 |
2022.08.08.TIL (0) | 2022.08.08 |