Oauth2.0 페이스북 로그인 완료
https://developers.facebook.com/
화면의 우측 상단 "내 앱"을 클릭한다.
"앱 만들기" 를 클릭한다.
필요한 부분에 체크를 하고 "다음"을 클릭한다.
필요한 부분에 체크하고 "다음"을 클릭한다.
필요한 부분을 입력하고 "앱 만들기"를 클릭한다.
"제품" 탭 -> "구성" -> "빠른시작"을 클릭한다.
"웹"을 클릭한다.
사이트 URL을 입력하고 "save"를 클릭한다.
"설정" -> "기본설정" 을 클릭하면 "앱 ID" 와 "앱 시크릿 코드"가 확인 가능하다.
application.yml
spring:
security:
oauth2:
client:
registration:
facebook:
client-id: 715406793918437
client-secret: 0a128db681ffec05a47782d01d1a4e78
scope:
- email
- public_profile
위의 yml형식을 참고하여 작성한다.
페이스북의 scope는 문서를 참고하면 구글과 달리 profile은 public_profile로 해야함을 알 수 있다.
loginFrom.html
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>로그인 페이지</title>
</head>
<body>
<h1>로그인 페이지</h1>
<hr/>
<form action="/login" method="POST">
<input type = "text" name = "username" placeholder="Username"/> <br/>
<input type = "password" name = "password" placeholder="Password"/> <br/>
<button>로그인</button>
</form>
<a href = "/oauth2/authorization/google">구글 로그인</a>
<a href = "/oauth2/authorization/facebook">페이스북 로그인</a>
<a href = "/joinForm">회원가입을 아직 하지 않음</a>
</body>
</html>
페이스북 로그인 버튼이 추가되었다.
/oauth2/authorization/facebook
Oauth2를 사용한다면 위의 URL은 고정이다.
각각의 로그인마다 form이 다르므로 이를 통합시켜서 처리될수 있도록 한다.
Oauth2UserInfo
package com.example.security1.config.oauth.provider;
public interface Oauth2UserInfo {
String getProviderId();
String getProvider();
String getEmail();
String getName();
}
Oauth2UserInfo 인터페이스를 만들어서 공통적으로 필요한 메서드들을 구현할 것이다.
GooogleUserInfo
package com.example.security1.config.oauth.provider;
import java.util.Map;
public class GoogleUserInfo implements Oauth2UserInfo{
private Map<String, Object> attributes; //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");
}
}
FacebookUserInfo
package com.example.security1.config.oauth.provider;
import java.util.Map;
public class FacebookUserInfo implements Oauth2UserInfo{
private Map<String, Object> attributes; //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");
}
}
페이스북의 id는 attributes에서 "id"를 해야하고
구글은 attributes에서 "sub"를 해야하므로 각각 다르게 구현해 주었다.
PrincipalOauth2UserService
package com.example.security1.config.oauth;
import com.example.security1.auth.PrincipalDetails;
import com.example.security1.config.oauth.provider.FacebookUserInfo;
import com.example.security1.config.oauth.provider.GoogleUserInfo;
import com.example.security1.config.oauth.provider.Oauth2UserInfo;
import com.example.security1.model.User;
import com.example.security1.repository.UserRepository;
import org.springframework.beans.factory.annotation.Autowired;
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 PrincipalOauth2UserService extends DefaultOAuth2UserService {
@Autowired
private UserRepository userRepository;
@Override
public OAuth2User loadUser(OAuth2UserRequest userRequest) throws OAuth2AuthenticationException {
System.out.println("getClientRegistration : " + userRequest.getClientRegistration());
System.out.println("getAccessToken : " + userRequest.getAccessToken().getTokenValue());
OAuth2User oAuth2User = super.loadUser(userRequest);
System.out.println("getAttributes : " + oAuth2User.getAttributes());
Oauth2UserInfo oAuth2UserInfo = null;
if(userRequest.getClientRegistration().getRegistrationId().equals("google")){
System.out.println("구글 로그인 요청");
oAuth2UserInfo = new GoogleUserInfo(oAuth2User.getAttributes());
} else if(userRequest.getClientRegistration().getRegistrationId().equals("facebook")) {
System.out.println("페이스북 로그인 요청");
oAuth2UserInfo = new FacebookUserInfo(oAuth2User.getAttributes());
} else {
System.out.println("구글과 페이스북 로그인만 가능합니다.");
}
String provider = oAuth2UserInfo.getProvider();
String providerId = oAuth2UserInfo.getProviderId();
String username = provider+"_"+providerId;
String email =oAuth2UserInfo.getEmail();
String role = "ROLE_USER";
User userEntity = userRepository.findByUsername(username);
if(userEntity == null) {
System.out.println("구글 로그인이 최초입니다.");
userEntity = User.builder()
.username(username)
.email(email)
.role(role)
.provider(provider)
.providerId(providerId)
.build();
userRepository.save(userEntity);
} else {
System.out.println("구글 로그인을 이미 한 적이 있습니다.");
}
return new PrincipalDetails(userEntity, oAuth2User.getAttributes());
}
}
provider를 확인하여 각각의 UserInfo 함수를 호출하여 필요한 값을 가져와
PrincipalDetails를 만든다.
Oauth2UserInfo oAuth2UserInfo = null;
if(userRequest.getClientRegistration().getRegistrationId().equals("google")){
System.out.println("구글 로그인 요청");
oAuth2UserInfo = new GoogleUserInfo(oAuth2User.getAttributes());
} else if(userRequest.getClientRegistration().getRegistrationId().equals("facebook")) {
System.out.println("페이스북 로그인 요청");
oAuth2UserInfo = new FacebookUserInfo(oAuth2User.getAttributes());
} else {
System.out.println("구글과 페이스북 로그인만 가능합니다.");
}
String provider = oAuth2UserInfo.getProvider();
String providerId = oAuth2UserInfo.getProviderId();
String username = provider+"_"+providerId;
String email =oAuth2UserInfo.getEmail();
String role = "ROLE_USER";
이전과는 이부분이 변경되거나 추가되었다.
'자바 탐구' 카테고리의 다른 글
JPA) 영속성 컨텍스트 (0) | 2023.07.21 |
---|---|
스프링) SpringSecurity - 11) Oauth2.0 네이버 로그인 완료 (0) | 2023.05.26 |
스프링) SpringSecurity - 9) Oauth2.0 구글 로그인 및 자동 회원 가입 진행 완료 (0) | 2023.05.26 |
스프링) SpringSecurity - 8) Oauth2.0 Authentication객체가 가질 수 있는 2가지 타입 (0) | 2023.05.26 |
스프링) SpringSecurity - 7) Oauth2.0 구글 회원 프로필 정보 받아보기 (0) | 2023.05.26 |