반응형
이 포스팅은 아래의 강의를 참고하였으니 여기에서 공부하시는 것을 추천드립니다.
이전 포스팅과 이어지는 내용입니다.
https://ajdahrdl.tistory.com/246
1. 페이스북 로그인 준비
더보기
1) Google에서 '페이스북 api 콘솔' 검색 후 페이스북 개발자 사이트.. 클릭
2) 우측 상단의 '시작하기' → 페이스북 로그인 → 내 앱 → 앱 만들기
3) 앱 유형은 '없음', 표시 이름은 자유롭게 설정 후 앱 만들기 완료
4) Facebook 로그인 기능을 사용할 것이기에 Facebook 로그인의 설정 버튼 클릭
5) 아래의 정보를 참고하여 설정 완료
- 앱의 플랫폼: 웹
- 사이트 URL: http://localhost:8080
- 나머지는 무시해도 무관(Spring Security & OAuth2를 이용할 것이기에)
6) '설정 - 기본 설정' 에서 앱 ID 와 앱 시크릿코드를 확인
2. Spring Boot 설정
1) pom.xml에 아래의 의존성(OAuth2 Client) 추가 및 application.yml에 아래처럼 설정
- pom.xml: OAuth2 Client 의존성이 이미 있으면 무시
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-oauth2-client</artifactId>
</dependency>
- application.yml
spring:
security:
oauth2:
client:
registration:
facebook:
client-id: ID입력
client-secret: 시크릿코드 입력
scope:
- email
- public_profile
2) 구글과 페이스북 로그인 차이점
providerId가 다르다. (google="sub", facebook="id")
인터페이스를 이용하여 유지보수가 간편하도록 소스를 작성한다.
a) OAuth2UserInfo 인터페이스 생성
package com.cos.security1.config.oauth2.provider;
public interface OAuth2UserInfo {
String getProviderId(); // pk
String getProvider(); // google, facebook, etc
String getEmail();
String getName();
}
b) GoogleUserInfo 인터페이스 생성
package com.cos.security1.config.oauth2.provider;
import java.util.Map;
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");
}
}
c) FacebookUserInfo 인터페이스 생성
package com.cos.security1.config.oauth2.provider;
import java.util.Map;
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");
}
}
d) PrincipalOauth2UserService 수정
package com.cos.security1.config.oauth2;
import com.cos.security1.Repository.UserRepository;
import com.cos.security1.config.auth.PrincipalDetails;
import com.cos.security1.config.oauth2.provider.FacebookUserInfo;
import com.cos.security1.config.oauth2.provider.GoogleUserInfo;
import com.cos.security1.config.oauth2.provider.OAuth2UserInfo;
import com.cos.security1.model.User;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.annotation.AuthenticationPrincipal;
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;
@Service
public class PrincipalOauth2UserSerivce extends DefaultOAuth2UserService {
@Autowired
private BCryptPasswordEncoder bCryptPasswordEncoder;
@Autowired
private UserRepository userRepository;
// 구글 로그인 작동 방식
// 구글로그인버튼 클릭 > 구글로그인 > code 리턴(OAuth-Client Library) > AccessToken 요청
// userRequest 정보 > loadUser함수 호출 > 구글로부터 회원 프로필을 받아줌
// 구글로부터 받은 userRequest 데이터에 대한 후처리 함수
// 함수 종료 시, @AuthenticationPrincipal 어노테이션이 만들어진다.
// OAuth2 로그인 시 사용
@Override
public OAuth2User loadUser(OAuth2UserRequest userRequest) throws OAuth2AuthenticationException{
System.out.println("getClientRegistration: "+userRequest.getClientRegistration()); // registration: 어떤 매체에서 로그인했는지 확인 가능
System.out.println("getAccessToken: "+userRequest.getAccessToken().getTokenValue()); // access token
System.out.println("getAttributes: "+super.loadUser(userRequest).getAttributes()); // 프로필 정보
OAuth2User oAuth2User = super.loadUser(userRequest);
System.out.println("getAttributes: "+oAuth2User.getAttributes());
String platform = userRequest.getClientRegistration().getRegistrationId(); // google, facebook, etc
OAuth2UserInfo oAuth2UserInfo = null;
if(platform.equals("google")){
System.out.println("Google을 이용한 로그인");
oAuth2UserInfo = new GoogleUserInfo(oAuth2User.getAttributes());
}else if(platform.equals("facebook")){
System.out.println("Facebook을 이용한 로그인");
oAuth2UserInfo = new FacebookUserInfo(oAuth2User.getAttributes());
}else{
System.out.println("다른 플랫폼임. 지원 X");
}
String provider = oAuth2UserInfo.getProvider();
String providerId = oAuth2UserInfo.getProviderId();
// OAuth2 로그인 시, username과 password는 필요없지만 형식상 넣어줌
String username = provider + "_" + providerId;
System.out.println("username: "+username);
String password = bCryptPasswordEncoder.encode("provider");
String role = "ROLE_USER";
String email = oAuth2UserInfo.getEmail();
User findUser = userRepository.findByUsername(username);
if(findUser == null){
findUser = User.builder()
.username(username)
.password(password)
.email(email)
.role(role)
.provider(provider)
.providerId(providerId)
.build();
userRepository.save(findUser);
}
return new PrincipalDetails(findUser, oAuth2User.getAttributes());
}
}
반응형
'BE > Spring' 카테고리의 다른 글
[Spring Security] JWT - 1. JWT를 공부하기 전에 (0) | 2022.06.09 |
---|---|
[Spring Security] 네이버 로그인하기 (0) | 2022.06.06 |
[Spring Security] oAuth2.0 - 구글로 로그인하기 (0) | 2022.06.02 |
[Spring Security] 계정 생성, 로그인 및 권한 처리 (0) | 2022.05.30 |
[스프링 입문 - 코드로 배우는 스프링 부트, 웹 MVC, DB 접근 기술] - 1일차 (0) | 2022.05.29 |