-
Spring Security - 페이스북 로그인Framework & Library/Spring Security 2021. 10. 4. 22:34
API 설정
프로젝트생성
ㆍ 페이스북 개발자 홈페이지에 접속을 한 후 위 사진에 표시된 "내 앱" 버튼을 클릭한다.
ㆍ "내 앱"에 접속한 후 "앱 만들기" 버튼을 클릭한다.
ㆍ 앱 유형을 "없음"으로 선택한 후 "다음" 버튼을 누른다.
ㆍ 표시 이름을 spring-security-basic으로 정한 후 "앱 만들기" 버튼을 클릭한다.
ㆍ 앱을 만든 후 Facebook 로그인 "설정" 버튼을 클릭한다.
ㆍ 설정에 들어온 뒤 "웹" 버튼을 클릭한다.
ㆍ 사이트 URL을 "http://localhost:8080"으로 설정한 후 "Save" 버튼을 눌러 저장한다.
ㆍ 설정 카테고리의 "기본 설정" 버튼을 누른 후 앱 ID와 앱 시크릿 코드를 확인하고 프로젝트 생성을 마무리한다.
Spring Security 설정
application.yml 파일 수정
ㆍ application.yml 파일에 위 코드를 추가하여 페이스북 로그인을 위한 설정을 마무리한다.
ㆍ client-id와 client-secret에는 페이스북 개발자 홈페이지에서 발급받은 앱 ID와 앱 시크릿 코드를 적는다.
loginForm.html 수정
ㆍ loginForm.html 파일에 페이스북 로그인을 수행할 수 있는 코드를 추가한다.
ㆍ "/oauth2/authorization/facebook" 주소는 OAuth Client 라이브러리를 사용하여 페이스북 로그인을 수행하기 위해 고정된 주소이다.
테스트
로그인 페이지
ㆍ 서버를 실행하고, 로그인 페이지에 접속한 후 페이스북 로그인 링크를 클릭한다.
페이스북 로그인 페이지
ㆍ 페이스북 로그인 링크에 접속한 후 본인의 페이스북 계정을 통해 페이스북 로그인을 수행한다.
로그인 결과 확인
ㆍ 로그인을 수행한 후 페이스북 로그인을 수행한 사용자의 정보가 콘솔 창에 잘 출력되고 있음을 확인할 수 있다.
소셜 로그인 별 사용자 정보의 관리
소셜 로그인 별 사용자 정보 관리의 필요성
ㆍ 구글 로그인과 페이스북 로그인 수행 시 전달받는 사용자 정보의 형태가 다르다.
ㆍ 그렇기 때문에 소셜 로그인의 종류마다 별도의 클래스를 만들어 관리를 해주어야 한다.
ㆍ 또한, 네이버와 카카오 같은 소셜 로그인 기능을 추가할 경우 유지보수가 훨씬 쉬워진다는 장점이 있다.
OAuth2UserInfo 인터페이스 생성
public interface OAuth2UserInfo { String getProviderId(); String getProvider(); String getEmail(); String getName(); }
ㆍ oauth 패키지에 provider 패키지를 생성한 후 OAuth2UserInfo 인터페이스를 생성한다.
ㆍ 소셜 로그인 별로 사용자의 정보를 받기 위한 인터페이스를 위 코드와 같이 작성한다.
GoogleUserInfo 클래스 생성
public class GoogleUserInfo implements OAuth2UserInfo { private Map<String, Object> attributes; // oAuth2User.getAttributes() public GoogleUserInfo(Map<String, Object> attributes) { this.attributes = attributes; } @Override public String getProviderId() { return (String) attributes.get("sub"); } @Override public String getProvider() { return "google"; } @Override public String getEmail() { return (String) attributes.get("email"); } @Override public String getName() { return (String) attributes.get("name"); } }
ㆍ provider 패키지 내에 구글 로그인을 수행한 사용자의 정보를 받기 위한 클래스인 GoogleUserInfo를 생성한다.
ㆍ 클래스를 생성한 후 OAuth2UserInfo 인터페이스를 구현하고 메서드들을 오버라이딩하는 방식이다.
FacebookUserInfo 클래스 생성
public class FacebookUserInfo implements OAuth2UserInfo { private Map<String, Object> attributes; // oAuth2User.getAttributes() public FacebookUserInfo(Map<String, Object> attributes) { this.attributes = attributes; } @Override public String getProviderId() { return (String) attributes.get("id"); } @Override public String getProvider() { return "facebook"; } @Override public String getEmail() { return (String) attributes.get("email"); } @Override public String getName() { return (String) attributes.get("name"); } }
ㆍ FacebookUserInfo 클래스 또한 GoogleUserInfo 클래스와 동일한 방식으로 생성한다.
PrincipalOauth2UserService 수정
@Override /* 구글로부터 받은 userRequest 데이터를 후처리하는 함수 */ public OAuth2User loadUser(OAuth2UserRequest userRequest) throws OAuth2AuthenticationException { System.out.println("getClientRegistration : " + userRequest.getClientRegistration()); // registrationId로 어떤 OAuth로 로그인 헸는지 확인 가능 System.out.println("getAccessToken : " + userRequest.getAccessToken()); OAuth2User oAuth2User = super.loadUser(userRequest); System.out.println("getAttributes : " + oAuth2User.getAttributes()); /* 소셜 로그인 수행시 강제 회원가입 */ OAuth2UserInfo oAuth2UserInfo = null; if (userRequest.getClientRegistration().getRegistrationId().equals("google")) { System.out.println("Google 로그인 요청"); oAuth2UserInfo = new GoogleUserInfo(oAuth2User.getAttributes()); } else if (userRequest.getClientRegistration().getRegistrationId().equals("facebook")) { System.out.println("Facebook 로그인 요청청"); oAuth2UserInfo = new FacebookUserInfo(oAuth2User.getAttributes()); } else { System.out.println("Google, Facebook 로그인만 지원합니다."); } String provider = oAuth2UserInfo.getProvider(); // ex) google String provideId = oAuth2UserInfo.getProviderId(); // ex) 103163902666771091884 String username = provider + "_" + provideId; // ex) google_103163902666771091884 String password = encoder.encode("겟인데어"); String email = oAuth2UserInfo.getEmail(); String role = "ROLE_USER"; User userEntity = userRepository.findByUsername(username); if (userEntity == null) { userEntity = User.builder() .username(username) .password(password) .email(email) .role(role) .provider(provider) .providerId(provideId) .build(); userRepository.save(userEntity); } else { System.out.println("소셜 계정으로 회원가입을 한 상태입니다."); } return new PrincipalDetails(userEntity, oAuth2User.getAttributes()); }
ㆍ PrincipalOauth2UserService 클래스 내의 loadUser() 메서드를 위 코드와 같이 수정한다.
ㆍ 메서드 내에 OAuth2UserInfo 객체를 선언하고, 소셜 로그인 종류별로 객체를 생성하여 로그인 사용자의 정보를 처리한다.
소셜 로그인 별 사용자 확인
ㆍ 로그인 페이지에서 구글 로그인, 페이스북 로그인, 일반 로그인을 한 사용자의 정보가 DB에 제대로 저장이 되었는지 확인해 본다.
ㆍ 로그인 방식 별로 사용자의 정보가 DB에 잘 저장되었음을 확인할 수 있다.
728x90'Framework & Library > Spring Security' 카테고리의 다른 글
Spring Security JWT - 프로젝트 생성 및 환경설정 (0) 2021.10.07 Spring Security - 네이버 로그인 (0) 2021.10.05 Spring Security - 구글 로그인 및 자동 회원가입 (0) 2021.10.04 Spring Security - Authentication 객체가 가질 수 있는 2가지 타입 (0) 2021.10.03 Spring Security - 구글 로그인 사용자 정보 받기 (0) 2021.10.02