1. 카카오톡 개발자 페이지에서 애플리케이션을 생성한다.

 

2. 플랫폼에서 Web 플랫폼 등록

 

3. Redirect URI 등록

- 두 개 모두 활성화시켜준다. 


[----> 여기서 Redirect URI를 내 마음대로 정했더니 이때부터 삽질 시작됨.. 2 ~ 3시간 동안 오류가 발생하는 원인을 찾고 고치고 엄청 고생함. 카카오톡 로그인 완료 후 토큰 값은 잘 나오는데 404페이지 에러가 발생함. 그래서 URI를 잘못 지정한 줄 알고 다시 수정.. 그래도 같은 오류가 발생.. 로그인 Controller에 카카오톡 리다이렉트 URI에서 루트 지정함. 404 에러는 발생하지 않지만, DB에 저장이 안 되고, Controller에서 view로 지정한 곳으로 이동만 함. 구글링에서는 토큰 값을 받아와 따로 저장하고 백엔드에서 다시 불러와야 된다고 나옴. 근데 공부할 때 OAuth2는 방금 언급한 토큰 값을 받아오고 사용하는 과장이 포함되는 라이브러리라고 배웠음. 처음부터 다시 차근차근해보니 Redirect URI와 Spring Security  OAuth2 Client 라이브러리를 잘 몰라서 실수한 오류였음...ㅜㅜ]


-> Spring Security OAuth2 Client 라이브러리를 사용할 때 Redirect URI는 OAutth2.0 에섯 사용자를 인증 서버로 리다이렉션 시키고, 사용자의 동의를 받은 후에 애플리케이션으로 다시 보내는 데 사용된다. 그래서 Redirect URI은 기본적으로 /localhost:8080/oauth2/code/{registrationId}로 리다이렉트 해준다. 이때 {registrationId}는 등록된 OAuth2.0 공급자의 아이디(Google, Kakao 등)이다.

 

4. REST API 키 저장

 

5. 내 애플리케이션 -> 보안 -> Client-Secret 발급받고 활성화시키기.

 

6. 내 애플리케이션 -> 동의항목 -> 개인정보 사용할 거 설정하기.

7. application.yml

security:
    user:
      name: test
      password: 1234
      
    oauth2:
      client:
        registration:
          kakao:
            client-id: 00000000000000000000
            client-secret: 00000000000000000000000
            scope:
              - profile_nickname
            authorization-grant-type: authorization_code
            redirect-uri: http://localhost:8080/login/oauth2/code/kakao
            client-name: Kakao
            client-authentication-method: POST
        
        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: id

- client-id : Rest API 키

- client-secret : 보안에서 받아온 Client-secret 키

- scope : 개인정보 동의 항목에서 받아온 값

===> 카카오톡은 provider를 작성해야 함.

 

8. SecurityConfig.java

.and()

.oauth2Login() : OAuth2.0 로그인 

.userInfoEndpoint() : OAuth2 공급자로부터 사용자 정보를 가져올 때의 구성을 설정(Scope에 해당하는 부분)

.userService(oauth2DetailService) : 사용자 정보를 가져오는 데 사용할 서비스 지정

 

9. OAuth2UserInfo.java

public interface OAuth2UserInfo {
	String getProviderId();
	String getProvider();
	String getEmail();
	String getName();
}

받아올 값은 같기 때문에 인터페이스를 만들어 준다.

 

10. KakaoUserInfo.java

카카오톡 개인 정보를 받아올 클래스 지정.. (OAuth2.0 공급자마다 제공하는 타입과 변수가 다르기 때문에)

@AllArgsConstructor
public class KakaoUserInfo implements OAuth2UserInfo{
	private Map<String, Object> attributes;

	@Override
	public String getProviderId() {
		return attributes.get("id").toString();
	}

	@Override
	public String getProvider() {
		return "kakao";
	}

	@Override
	public String getEmail() {
		return null;
	}

	@Override
	public String getName() {
		//kakao_account라는 Map에서 추출
		return (String)((Map)attributes.get("properties")).get("nickname");
	}
}

 

 

11. OAuth2DetailsService.java

@RequiredArgsConstructor
@Service
@Slf4j
public class OAuth2DetailsService extends DefaultOAuth2UserService{
	private final UserRepository userRepository;
	
	@Override
	public OAuth2User loadUser(OAuth2UserRequest userRequest) throws OAuth2AuthenticationException{
		OAuth2User oauth2User = super.loadUser(userRequest);
		log.info("getAttributes: {}", oauth2User.getAttributes());
		
		OAuth2UserInfo oAuth2UserInfo = null;
		
		String provider = userRequest.getClientRegistration().getRegistrationId();
		
		if(provider.equals("kakao")) {
			log.info("카카오 로그인 요청");
			oAuth2UserInfo = new KakaoUserInfo((Map)oauth2User.getAttributes());
		}
		
		String providerId = oAuth2UserInfo.getProviderId();
		String password = new BCryptPasswordEncoder().encode(UUID.randomUUID().toString());
		String email = oAuth2UserInfo.getEmail();
		if(email == null) {
			email = " ";
		}
		String username = provider + "_" + providerId;
		String name = oAuth2UserInfo.getName();
		
		User userEntity = userRepository.findByUsername(username);
		
		log.info(username);
		if(userEntity == null) { //최초 로그인
			User user = User.builder()
				.username(username)
				.password(password)
				.email(email)
				.name(name)
				.role("ROLE_USER")
				.build();
			
			return new PrincipalDetails(userRepository.save(user), oauth2User.getAttributes());
		}else {
			return new PrincipalDetails(userEntity, oauth2User.getAttributes());
		}
		
		
	}
}

이런 식으로 저장이 된다.

 

12. href = '/oauth2/authorization/kakao'  

+ Recent posts