Table of Contents
Facebook/Kakao Login
개발환경
- Spring Boot 2.1.x
- Gradle 4.10.2
파일 수정 및 추가
src/main/java/kr/co/episode/example/config/oauth2/dto/OAuthAttributes.java
@Getter
public class OAuthAttributes {
// ......
public static OAuthAttributes of(String registrationId, String userNameAttributeName, Map<String, Object> attributes) {
//System.out.println(registrationId);
//System.out.println(attributes);
if ("naver".equals(registrationId)) {
return ofNaver("id", attributes);
}
if ("facebook".equals(registrationId)) {
return ofFacebook("id", attributes);
}
if ("kakao".equals(registrationId)) {
return ofKakao("id", attributes);
}
return ofGoogle(userNameAttributeName, attributes);
}
// ......
private static OAuthAttributes ofFacebook(String userNameAttributeName, Map<String, Object> attributes) {
// 아래의 경우, 이메일을 반환하지 않는다.
// No Email address on account
// No confirmed email address on account
// No verified email address on account
// https://stackoverflow.com/questions/17532476/facebook-email-field-return-null-even-if-the-email-permission-is-set-and-acce
String email = (String) attributes.get("email");
if (email == null) {
email = ((String) attributes.get("name")) + "@facebook.com";
}
Map<String, Object> picture = (Map<String, Object>) attributes.get("picture");
Map<String, Object> picture_data = (Map<String, Object>) picture.get("data");
String picture_url = (String) picture_data.get("url");
return OAuthAttributes.builder()
.name((String) attributes.get("name"))
.email(email)
.picture(picture_url)
.attributes(attributes)
.nameAttributeKey(userNameAttributeName)
.build();
}
private static OAuthAttributes ofKakao(String userNameAttributeName, Map<String, Object> attributes) {
Map<String, Object> properties = (Map<String, Object>) attributes.get("properties");
Map<String, Object> kakao_account = (Map<String, Object>) attributes.get("kakao_account");
String name = (String) properties.get("nickname");
String email = (String) kakao_account.get("email");
String picture = (String) properties.get("profile_image");
return OAuthAttributes.builder()
.name(name)
.email(email)
.picture(picture)
.attributes(attributes)
.nameAttributeKey(userNameAttributeName)
.build();
}
// ......
}
src/main/resources/application.properties
# =========================================================
# Facebook OAuth2
# =========================================================
spring.security.oauth2.client.registration.facebook.client-id=<user client-id>
spring.security.oauth2.client.registration.facebook.client-secret=<user secret>
spring.security.oauth2.client.registration.facebook.scope=profile,email
spring.security.oauth2.client.provider.facebook.user-info-uri=https://graph.facebook.com/me?fields=email,name,locale
# =========================================================
# Kakao OAuth2
# =========================================================
spring.security.oauth2.client.registration.kakao.client-id=<user client-id>
spring.security.oauth2.client.registration.kakao.client-secret=<user secret>
spring.security.oauth2.client.registration.kakao.authorization-grant-type=authorization_code
spring.security.oauth2.client.registration.kakao.redirect-uri={baseUrl}/{action}/oauth2/code/{registrationId}
spring.security.oauth2.client.registration.kakao.scope=profile,account_email
spring.security.oauth2.client.registration.kakao.client-name=Kakao
spring.security.oauth2.client.registration.kakao.client-authentication-method=POST
spring.security.oauth2.client.provider.kakao.token-uri=https://kauth.kakao.com/oauth/token
spring.security.oauth2.client.provider.kakao.authorization-uri=https://kauth.kakao.com/oauth/authorize
spring.security.oauth2.client.provider.kakao.user-info-uri=https://kapi.kakao.com/v2/user/me
spring.security.oauth2.client.provider.kakao.user-name-attribute=id
src/main/resources/templates/index.html
<h1>스프링 부트 게시판</h1>
<div class="col-md-12">
<div class="row">
<div class="col-md-6">
<a href="/posts/save" role="button" class="btn" btn-primary>글 등록</a>
<div th:if="${userName != null}" th:inline="text">
[[${userName}]] 님, 안녕하세요.
<a href="/logout" class="btn btn-info active" role="button">로그아웃</a>
</div>
<div th:if="${userName == null}">
<a href="/oauth2/authorization/google" class="btn btn-success active" role="button">구글 로그인</a>
<a href="/oauth2/authorization/facebook" class="btn btn-success active" role="button">페이스북 로그인</a>
<a href="/oauth2/authorization/naver" class="btn btn-success active" role="button">네이버 로그인</a>
<a href="/oauth2/authorization/kakao" class="btn btn-success active" role="button">카카오 로그인</a>
</div>
</div>
</div>
</div>
<div style="height: 80px;">
</div>