[TaskApp] KAKAO 로그인 구현 하기
구글, 네이버 로그인에 이어 카카오 로그인을 구현하겠다.
1. KAKAO OAuth 서비스 등록하기
Kakao Developers
카카오 API를 활용하여 다양한 어플리케이션을 개발해보세요. 카카오 로그인, 메시지 보내기, 친구 API, 인공지능 API 등을 제공합니다.
developers.kakao.com
1-1) 애플리케이션 추가하기
"애플리케이션 추가하기" 를 클릭한다.
애플리케이션 추가하기 > 앱 이름 : "task app project"
> 회사명 : "개인"
> 카테고리 : "라이브러리/데모"
※ '회사명' , '카테고리' 는 임의로 작성하였다.
"저장" 버튼을 클릭하여 애플리케이션을 추가한다.
추가된 애플리케이션 "task app project" 를 확인할 수 있다.
"task app project" 를 클릭하여, 애플리케이션의 설정으로 접속한다.
1-2) 애플리케이션 설정하기
카카오 로그인 > 활성화 설정 > 상태 : "ON"
OpenID Connent 활성화 설정 > 상태 : "ON"
Redirect URL : 추가 - "http://localhost:8080/login/oauth2/code/kakao"
이 부분이 중요하다.
동의항목 > 개인정보 > '닉네임' , '카카오계정(이메일)' - "필수동의"
[문제 상황 - 동의항목 (카카오계정(이메일) 추가하기)]
여기서 '닉네임' 은 "사용 안 함" 으로 설정 되어 있고, 이를 "필수 동의" 로 변경할 수 있었지만,
'카카오계정(이메일)' 은 "권한없음" 으로 설정되어 있다.
이 것은 "비즈 앱" 으로 설정되어 있지 않기 때문이다.
이전에는 "비즈 앱" 으로 설정 되어 있지 않았어도, 이메일 정보를 사용가능 했지만, 최근 "비즈 앱" 에 한해서 이메일 정보를 사용가능하도록 제한 해 둔 것 같다.
따라서 "비즈 앱" 으로 현재 애플리케이션을 등록해야 한다.
위 이미지는 이미 비즈 앱으로 등록된 애플리케이션의 화면이다.
내 애플리케이션> 앱 설정 > 비즈니스 > 비즈 앱 등록 을 통해 비즈 앱으로 등록한다.
※ 비즈 앱 등록은 안내를 쭉 따라가면 되기 때문에, 설명은 생략하겠다.
(비즈 앱 등록을 위해선 애플리케이션 대표 이미지를 등록해야 한다.)
1-3) "Client Secret" , "Client ID" 확인하기
보안 > Client Secret > 코드
Client Secret 를 확인한다.
앱 키 > 앱 키 > REST API 키
키를 확인한다.
2. application-oauth.yml 에 KAKAO OAuth 정보 등록하기
spring:
security:
oauth2:
client:
registration:
#GOOGLE 'client-id' , 'client-secret' , 'scope'
# google 생략
#KAKAO 'client-id' , 'client-secret' , 'scope'
kakao:
client-id: "your-kakao-client-id"
client-secret: "your-kakao-client-secret"
scope:
- profile_nickname
- account_email
#KAKAO Spring Security 수동 입력
redirect-uri: http://localhost:8080/login/oauth2/code/kakao
authorization-grant-type: authorization_code
client-name: Kakao
client-authentication-method: client_secret_post
#NAVER 'client-id' , 'client-secret' , 'scope'
#NAVER Spring Security 수동 입력
# naver 생략
provider:
#NAVER provider 등록
# naver provider 생략
#KAKAO provider 등록
kakao:
authorization-uri: https://kauth.kakao.com/oauth/authorize
token-uri: https://kauth.kakao.com/oauth/token
user-info-uri: https://kapi.kakao.com/v2/user/me
user-name-attribute: kakao_account
<KAKAO 'client-id' , 'client-secret' , 'scope' 등록>
'client-id' 는 앞서 확인한 'REST_API 키' 이다.
'client-secret' 는 앞서 확인한 'client-secret' 코드 이다.
'scope' 는 동의항목에 있는 항목의 ID 를 입력한다. "profile_nickname" , "account_email"
<KAKAO Spring Security 수동 입력>
#KAKAO Spring Security 수동 입력
redirect-uri: http://localhost:8080/login/oauth2/code/kakao
authorization-grant-type: authorization_code
client-name: Kakao
client-authentication-method: client_secret_post
네이버와 모두 동일하지만, 'client-authentication-method: client_secret_post' 가 추가되었다.
스프링 부트의 버전이 2.x.x 에서 3.x.x 로 넘어가면서 추가되었다.
보안을 위해 'client-secret' 를 사용하는데, 이를 적극적으로 명시해주기 위함이다.
※ 만약 'client-authentication-method: client_secret_post' 을 추가하지 않으면,
이 오류가 발생하게 된다.
<KAKAO provider 등록>
#KAKAO provider 등록
kakao:
authorization-uri: https://kauth.kakao.com/oauth/authorize
token-uri: https://kauth.kakao.com/oauth/token
user-info-uri: https://kapi.kakao.com/v2/user/me
user-name-attribute: kakao_account
네이버와 마찬가지로 provider 를 등록해야 한다.
3. OAuthAttributes.class
@AllArgsConstructor
@NoArgsConstructor
@Builder
@Getter
@ToString
public class OAuthAttributes {
private Map<String, Object> attributes;
private String nameAttributeKey;
private String username;
private String email;
private UserRole role;
//인증자가 누구인지 구분 메서드
public static OAuthAttributes of(String registrationId,
String usernameAttributeName,
Map<String, Object> attributes) {
//1. Google
if (registrationId.equals("google")) {
return ofGoogle(usernameAttributeName, attributes);
}
//2. Kakao
if (registrationId.equals("kakao")) {
return ofKakao(usernameAttributeName, attributes);
}
//3. Naver
if (registrationId.equals("naver")) {
return ofNaver(usernameAttributeName, attributes);
}
return null;
}
private static OAuthAttributes ofKakao(String usernameAttributeName, Map<String, Object> attributes) {
Map<String, Object> response = (Map<String, Object>) attributes.get("kakao_account");
return OAuthAttributes.builder()
.username((String) response.get("email"))
.email((String) response.get("email"))
.attributes(response)
.nameAttributeKey(usernameAttributeName)
.build();
}
/*ofNaver 메서드 생략*/
/*ofGoogle 메서드 생략*/
}
}
"KakaoAccount" 의 속성에 "email" 속성을 가져온다.
4. Thymeleaf
<!--login.html 中...-->
<!--간편 로그인-->
<div class="social-login-container">
<!--구글 로그인-->
<a href="/oauth2/authorization/google" role="button" class="social-login-btn">
<img src="/img/google-logo.png" alt="google-login" class="login-img"/>
구글로 로그인
</a>
<!--네이버 로그인-->
<a href="/oauth2/authorization/naver" role="button" class="social-login-btn" style="background: #1EC800;">
<img src="/img/naver-logo.png" alt="naver-login" class="login-img"/>
네이버로 로그인
</a>
<!--카카오 로그인-->
<a href="/oauth2/authorization/kakao" role="button" class="social-login-btn" style="background: #FEE500;">
<img src="/img/kakao-logo.png" alt="kakao-login" class="login-img"/>
카카오로 로그인
</a>
</div>
"/oauth2/authorization/kakao" 로 URL 을 설정한다.
5. 완성 화면
소셜 로그인으로 로그인 된 회원이 DB에 추가된 것을 확인할 수 있다.