Wanna be Brilliant Full-Stack Developer

2/22 SpringBoot 페이스북 로그인 구현 완료 본문

Back-End/Spring Boot

2/22 SpringBoot 페이스북 로그인 구현 완료

Flashpacker 2022. 2. 22. 11:56


package com.cos.photogramstart.config.oauth;

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 com.cos.photogramstart.domain.user.User;
import com.cos.photogramstart.domain.user.UserRepository;

import lombok.RequiredArgsConstructor;

@RequiredArgsConstructor
@Service
public class OAuth2DetailsService extends DefaultOAuth2UserService {
	
	private final UserRepository userRepository;
	
	@Override
	public OAuth2User loadUser(OAuth2UserRequest userRequest) throws OAuth2AuthenticationException {
		System.out.println("OAuth2 서비스 탐");
		OAuth2User oAuth2User = super.loadUser(userRequest);
		System.out.println(oAuth2User.getAttributes());
		
		User userEntity = userRepository.save(null);
		return null;
	}

}

유저정보를 저장하기 위해서 유저정보를 만들어야한다! 회원가입할떄 username, password , email , name은 꼭 받아야한다. 

User user = User.builder()
.username(null)
.password(null)
.email(null)
.name(null)
.build(); 해서 user를 세이브하면된다! 

package com.cos.photogramstart.config.oauth;

import java.util.Map;
import java.util.UUID;

import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
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 com.cos.photogramstart.domain.user.User;
import com.cos.photogramstart.domain.user.UserRepository;

import lombok.RequiredArgsConstructor;

@RequiredArgsConstructor
@Service
public class OAuth2DetailsService extends DefaultOAuth2UserService {
	
	private final UserRepository userRepository;
	private final BCryptPasswordEncoder bCryptPasswordEncoder;
	
	@Override
	public OAuth2User loadUser(OAuth2UserRequest userRequest) throws OAuth2AuthenticationException {
		System.out.println("OAuth2 서비스 탐");
		OAuth2User oAuth2User = super.loadUser(userRequest);
		System.out.println(oAuth2User.getAttributes());
		
		Map<String, Object> userInfo = oAuth2User.getAttributes();
		
		String username = "Facebook_"+(String) userInfo.get("id");
		String password = bCryptPasswordEncoder.encode(UUID.randomUUID().toString());
		String email = (String) userInfo.get("email");
		String name = (String) userInfo.get("name");
		
		
		User user = User.builder()
				.username(username)
				.password(password)
				.email(email)
				.name(name)
				.build();
		User userEntity = userRepository.save(user);
		return null;
	}

}
package com.cos.photogramstart.config.auth;

import java.util.ArrayList;
import java.util.Collection;
import java.util.Map;

import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.oauth2.core.user.OAuth2User;

import com.cos.photogramstart.domain.user.User;

import lombok.Data;

@Data
public class PrincipalDetails implements UserDetails, OAuth2User{


	private static final long serialVersionUID = 1L;

	private User user;
	private Map<String, Object> attributes;
	
	public PrincipalDetails(User user) {
		this.user = user;
	}
	
	public PrincipalDetails(User user, Map<String, Object> attributes ) {
		this.user = user;
	}
	// 권한: 한개가 아닐 수 있음. (3개 이상의 권한) 
	@Override
	public Collection<? extends GrantedAuthority> getAuthorities() {
		
		Collection<GrantedAuthority> collector = new ArrayList<>();
		collector.add(() ->  {	return user.getRole();});
		return collector;
		
	}

	@Override
	public String getPassword() {
		return user.getPassword();
	}

	@Override
	public String getUsername() {
		return user.getUsername();
	}

	@Override
	public boolean isAccountNonExpired() {
		return true;
	}

	@Override
	public boolean isAccountNonLocked() {
		return true;
	}

	@Override
	public boolean isCredentialsNonExpired() {
	return true;
	}

	@Override
	public boolean isEnabled() {
		return true;
	}

	@Override
	public Map<String, Object> getAttributes() {
		return attributes; // {id: 34314134134134, name:김도원, email:gkrskfo@nate.com}
	}

	@Override
	public String getName() {
		// TODO Auto-generated method stub
		return (String) attributes.get("name");
	}

}

이렇게 한경우 Oauth로 로그인 한경우 attributes 정보들이 있을것이고 일반적으로 로그인 한경우에는 없을것이다.

오버로딩을 해놨으니 Oauth 로그인 할떄는 public PrincipalDetails(User user, Map<String, Object> attributes ) {
this.user = user;
} 떄려놓을 것이고 

 

 

The dependencies of some of the beans in the application context form a cycle:

 

DI에 사이클에 문제가 있다는것은 우리가 스프링이 실행될때 어노테이션을 끄고 IOC로 등록을 하는데 

OAuth2DetailsService 보다 시큐리티가 메모리에 늦게 떴다는것이다.