minlog
article thumbnail

 

기존 프로젝트는 소셜 로그인으로 구글을 받고 있었습니다.

네이버 로그인과 카카오 로그인 기능도 추가하여 리팩토링 해보았습니다.

 

 

 

1. NAVER 소셜 로그인

 

01. API 신청

naver developers 사이트에서 Application을 등록해줍니다. 

1) 애플리케이션 등록

  • 애플리케이션 이름
  • 사용 API  : 네이버 로그인 선택
    • 제공 받을 정보를 선택 할 수 있다.
  • 로그인 오픈 API 서비스 환경 : PC웹
    • 서비스 URL : http://localhost:8087/
    • Callback URL : http://localhost:8087/login/oauth2/code/naver

 

 

애플리케이션 - NAVER Developers

 

developers.naver.com

 

02. 프로젝트 내 설정

 
프로젝트에 소셜 로그인을 적용하기 위해서는 build.gradle 에 'spring-boot-starter-oauth2-client'를 추가해주어야한다.

이미 앞에 구글 로그인을 구현할 때 해당 코드를 추가하였기 때문에 나는 properties 설정만 추가해주었다.

1) 빌드설정

 📑 build.gradle 

    implementation 'org.springframework.boot:spring-boot-starter-oauth2-client'//구글소셜로그인

 
 

2) Properties 설정

내부에 들어가는 내용은 네이버 '애플리케이션 정보'에서 확인할 수 있다.

  • 기본 설정
    • client-id : 네이버 Client ID
    • client-secret : 네이버 Client Secret
    • redirect-uri : {애플리케이션URL}/login/oauth2/code/naver
    • scope :  내가 받아오기로한 정보들의 명칭을 넣어주면된다.
    • client-name : Naver
  • provider : 네이버 로그인은 기본 스프링에서 제공하는 시큐리티를 허용하지 않아 설정이 필요하다.

 

📑 applicaiton-oauth.properties 

더보기
# naver
spring.security.oauth2.client.registration.naver.client-id= 네이버 Client ID 
spring.security.oauth2.client.registration.naver.client-secret= 네이버 Client Secret 
spring.security.oauth2.client.registration.naver.redirect-uri=http://localhost:8087/login/oauth2/code/naver
spring.security.oauth2.client.registration.naver.authorization-grant-type=authorization_code
spring.security.oauth2.client.registration.naver.scope=name,mobile,profile_image
spring.security.oauth2.client.registration.naver.client-name=Naver


# provider
spring.security.oauth2.client.provider.naver.authorization-uri=https://nid.naver.com/oauth2.0/authorize
spring.security.oauth2.client.provider.naver.token-uri=https://nid.naver.com/oauth2.0/token
spring.security.oauth2.client.provider.naver.user-info-uri=https://openapi.naver.com/v1/nid/me
spring.security.oauth2.client.provider.naver.user-name-attribute=response

 

 

03. Service 로직 수정 

네이버의 경우 response 안에 key, value의 형태로 내가 필요하는 정보들을 담고 있다.

Map map = (Map) oAuth2User.getAttributes().get("response");  의 형태로 값을 추출하여 사용할 수 있다.

 

📑UserTravelOAuth2DetailService.java

더보기
package com.example.travel.security.service;

import com.example.travel.domain.UserImage;
import com.example.travel.domain.UserRole;
import com.example.travel.domain.UserTravel;
import com.example.travel.repository.member.UserImageRepository;
import com.example.travel.repository.member.UserRepository;
import com.example.travel.security.dto.UserTravelAdapter;
import com.example.travel.service.FileService;
import lombok.RequiredArgsConstructor;
import lombok.extern.log4j.Log4j2;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.security.oauth2.client.userinfo.DefaultOAuth2UserService;
import org.springframework.security.oauth2.client.userinfo.OAuth2UserRequest;
import org.springframework.security.oauth2.core.OAuth2AuthenticationException;
import org.springframework.security.oauth2.core.user.OAuth2User;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.Map;
import java.util.Optional;

@Log4j2
@Service
@RequiredArgsConstructor
public class UserTravelOAuth2DetailService extends DefaultOAuth2UserService {
    private final UserRepository userRepository;
    private final PasswordEncoder passwordEncoder;

    // 이미지 관련 추가
    private final UserImageRepository userImageRepository;


    @Transactional
    @Override
    public OAuth2User loadUser(OAuth2UserRequest userRequest) throws OAuth2AuthenticationException {
        log.info("social login =============================");
        String clientName = userRequest.getClientRegistration().getClientName();
        log.info("clientName : {}",clientName);
        log.info("clientName : {}",userRequest.getAdditionalParameters());

        OAuth2User oAuth2User = super.loadUser(userRequest);
        oAuth2User.getAttributes().forEach((k,v)->{
            log.info(k+":"+v);
        });

        //회원가입

        // 1. 이메일 추출
        String email = null;
        String picture = null;
        String name = null;
        String mobile = null;

        if (clientName.equals("Google")){
            email = oAuth2User.getAttribute("email");
            picture =oAuth2User.getAttribute("picture");


        }else if(clientName.equals("Naver")){  // 추가된 내용 1
            log.info("네이버");
            Map map = (Map) oAuth2User.getAttributes().get("response");
            email =(String)map.get("email");
            picture =(String)map.get("profile_image");
            name = (String)map.get("name");
            mobile = (String)map.get("mobile");
        }


        Optional<UserTravel> userByUserIdAndUserSocial = userRepository.getUserByUserIdAndUserSocial(email, true);

        if (userByUserIdAndUserSocial.isPresent()){
            log.info("OAuth 유저가 있을 경우");
			...

        }


        // 2. 회원가입 로직
        log.info("userOAuth Google 회원가입 로직 ===============");
        UserTravel userOAuth = UserTravel.builder()
                .userEmail(email)
                .userId(email)
                .name(name) // 추가된 내용 2
                .userPhone(mobile) // 추가된 내용 3
                .password(passwordEncoder.encode("1111"))
                .userSocial(true)
                .build();
        userOAuth.roleAdd(UserRole.USER); // 권한 추가

        UserImage build = UserImage.builder().build(); //저장할 이미지
        if (picture != null){ // 이미지가 있을경우
            log.info("이미지가 존재");
            build.setOriginFileName(picture);
        }else{
            log.info("이미지가 없음");
        }


        UserImage ImageSaveResult = userImageRepository.save(build); // 이미지 저장
        userOAuth.updateUserImage(ImageSaveResult);
        UserTravel save = userRepository.save(userOAuth);  // 회원 저장
        UserTravelAdapter userTravelAdapter = new UserTravelAdapter(save, oAuth2User.getAttributes());
        userTravelAdapter.setProfile(ImageSaveResult.getOriginFileName());
        return userTravelAdapter;

    }


}

 

 

 


 

2. KAKAO 소셜 로그인

 

01. API 신청

kakao developers 사이트에서 Application을 등록해줍니다. 

 

Kakao Developers

카카오 API를 활용하여 다양한 어플리케이션을 개발해보세요. 카카오 로그인, 메시지 보내기, 친구 API, 인공지능 API 등을 제공합니다.

developers.kakao.com

 

1) 애플리케이션 등록

  • 애플리케이션 추가하기
  • 내애플리케이션 > 앱설정 플랫폼 > web플랫폼 등록
    • http://localhost:8087

 

  • 내 애플리케이션 > 제품설정 > 카카오로그인 
    • 활성화 설정을 ON해준다.
    • Redirect URL : http://localhost:8087/login/oauth2/code/kakao
  • 내 애플리케이션 > 제품설정 > 카카오로그인 > 동의항목 
    • 필요한 정보들을 선택해준다.

 

 

02. 프로젝트 내 설정

1) Properties 설정

내부에 들어가는 내용은 카카오 '애플리케이션 정보'에서 확인할 수 있다.

  • 기본 설정
    • client-id: 카카오 REST API키
    • redirect-uri : {애플리케이션URL}/login/oauth2/code/naver
    • scope :  내가 받아오기로한 정보들의 명칭을 넣어주면된다.
    • client-name : Naver

 

📑 applicaiton-oauth.properties

더보기
# kakao
spring.security.oauth2.client.registration.kakao.client-id=c5793eb91831850104a678950c4fbac2
spring.security.oauth2.client.registration.kakao.redirect-uri=http://localhost:8087/login/oauth2/code/kakao
spring.security.oauth2.client.registration.kakao.client-authentication-method= POST
spring.security.oauth2.client.registration.kakao.authorization-grant-type=authorization_code
spring.security.oauth2.client.registration.kakao.scope=profile_nickname,profile_image,account_email
spring.security.oauth2.client.registration.kakao.client-name= Kakao
spring.security.oauth2.client.provider.kakao.authorization_uri = https://kauth.kakao.com/oauth/authorize
spring.security.oauth2.client.provider.kakao.token_uri= https://kauth.kakao.com/oauth/token
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

 

 

03. Service 로직 수정 

카카오의 경우 kakao_account 안에 key, value의 형태로 내가 필요하는 정보들을 담고 있다.

Map map = (Map) oAuth2User.getAttributes().get("kakao_account");  의 형태로 값을 추출하여 사용할 수 있다.

 

📑UserTravelOAuth2DetailService.java

더보기
...
	if(clientName.equals("Kakao")){
        log.info("카카오");
        Map kakaoAccount = (Map)oAuth2User.getAttributes().get("kakao_account");
        Map profile = (Map) kakaoAccount.get("profile");

        email =(String)kakaoAccount.get("email");
        picture =(String)profile.get("profile_image_url");
        name = (String)profile.get("nickname");
    }
    
    
...
profile

minlog

@jimin-log

포스팅이 좋았다면 "좋아요❤️" 또는 "구독👍🏻" 해주세요!