[From Hello To QueryDSL] Facebook/Kakao Login (11/12)

By | 2020년 3월 21일
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>

답글 남기기