일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | 5 | 6 | 7 |
8 | 9 | 10 | 11 | 12 | 13 | 14 |
15 | 16 | 17 | 18 | 19 | 20 | 21 |
22 | 23 | 24 | 25 | 26 | 27 | 28 |
29 | 30 |
- 인스타클론
- springboot_exception_handler
- 출처 문어박사
- 스프링부트api
- ssh도커설치
- 스프링부트서버에사진전송
- 스프링부트
- centos도커설치
- 출처 따배도
- 도커설치하는법
- 스프링이미지업로드
- 스프링부트중복예외처리
- 스프링사진업로드
- 스프링사진
- WAS웹서버
- vm도커설치하는법
- 서버에도커설치
- 파이썬sort
- 스프링부트팔로잉
- dockerinstall
- 스프링부트구독취소
- 출처 노마드코더
- 출처 메타코딩
- 스프링구독
- 멀티폼
- 스프링부트팔로우취소
- 출처 코딩셰프
- 스프링부트사진올리기
- 스프링익셉션처리
- 우분투도커설치
- Today
- Total
MakerHyeon
[SpringBoot] Security 구글 로그인 본문
● 구글 로그인 준비하기
0. 프로젝트 생성
1. oauth 동의안구성
2. 사용자인증정보 -> Oauth client ID 만들기 -> 승인된 redirection(http://localhost:8080/login/oauth2/code/google)
3. dependency 추가
// build.gradle dependency 추가
implementation 'org.springframework.boot:spring-boot-starter-oauth2-client'
4. application.yml에 키 등록
security:
oauth2:
client:
registration:
google:
client-id: 658211206947-ephbghihhrh662n8ks32ijhlnnlk91dq.apps.googleusercontent.com
client-secret: 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
scope:
- email
- profile
5. 로그인(고정링크) 링크 생성
// loginForm.html
<a href="/oauth2/authorization/google">구글 로그인</a>
6. SecurityConfig 설정
// SecurityConfig.java
...
.defaultSuccessUrl("/")
.and()
.oauth2Login()
.loginPage("/loginForm"); // 구글 로그인 완료 후 후처리가 필요함
return http.build();
}
● 구글 회원 정보 받아오기
1) 코드받기 (인증)
2) 액세스토큰 (권한)
3) 사용자프로필 정보를 가져오고
4-1) 그 정보를 토대로 회원가입을 자동으로 진행시키기도 한다.
4-2) 집주소등 추가적인 주소가 필요하면 추가적 회원가입창으로 보낸다.
구글 로그인이 완료된 후에는 코드를 받지않고 액세스토큰과 사용자프로필정보를 바로 받는다.
7. PrincipalOauth2UserService 파일 생성
// PrincipalOauth2UserService.java
@Service
public class PrincipalOauth2UserService extends DefaultOAuth2UserService {
// 구글로부터 받은 userRequest 데이터에 대한 후처리가 되는 함수
@Override
public OAuth2User loadUser(OAuth2UserRequest userRequest) throws OAuth2AuthenticationException {
// System.out.println("getClientRegistration: "+userRequest.getClientRegistration());
// System.out.println("getAccessToken: "+userRequest.getAccessToken().getTokenValue());
// System.out.println("getAttributes: "+super.loadUser(userRequest).getAttributes());
return super.loadUser(userRequest);
}
}
실행결과:
- registrationId로 어떤 OAuth로 로그인 했는지 확인 가능.
- 구글로그인 버튼 클릭 -> 구글로그인창 -> 로그인 완료-> code를 리턴(OAuth-Client라이브러리) -> AccessToken요청
- userRequest 정보 -> loadUser 함수 호출 -> 회원프로필 받아줌
결과: getClientRegistration: ClientRegistration{registrationId='google', clientId='658211206947-ephbghihhrh662n8ks32ijhlnnlk91dq.apps.googleusercontent.com', clientSecret='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', clientAuthenticationMethod=org.springframework.security.oauth2.core.ClientAuthenticationMethod@4fcef9d3, authorizationGrantType=org.springframework.security.oauth2.core.AuthorizationGrantType@5da5e9f3, redirectUri='{baseUrl}/{action}/oauth2/code/{registrationId}', scopes=[email, profile], providerDetails=org.springframework.security.oauth2.client.registration.ClientRegistration$ProviderDetails@155e2571, clientName='Google'} getAccessToken: ya29.a0AX9GBdXYx8t9s6j48WgCHZecwAedRIKWZYrDMh7RB6RpAI5zSaQEw8xKoWloigiWw95zuapTEEAYhm2FxHtSQF7YtJXDHvmIb4XCXkAjq7fu0q2QZYmULwb-X3OnpZSFEH-V5VybSYuiPB_E8eD7jdpt7ErraCgYKAfMSARASFQHUCsbCLmWrMnCFRb3jL5iexAsKpw0163 getAttributes: {sub=111633286854698474532, name=보노보노처럼살래, given_name=처럼살래, family_name=보노보노, picture=https://lh3.googleusercontent.com/a/AEdFTp5_v6xJfWQerJ01KvBLjIj2nHj6hxyRqPpyIMmrOA=s96-c, email=hyeonkjjang@gmail.com, email_verified=true, locale=ko}
8. SecurityConfig 설정
.defaultSuccessUrl("/")
.and()
.oauth2Login()
.loginPage("/loginForm")
.userInfoEndpoint()
.userService(principalOauth2UserService);
return http.build();
● Authentication객체가 가질수 있는 2가지 타입
● 구글 로그인 및 자동 회원가입 진행 완료
- PrincipalDetails implements UserDetails, OAuth2User
// PrincipalDetails.java
private Map<String,Object> attributes;
// Map
@Override
public Map<String, Object> getAttributes() {
return attributes;
}
// 생성자
// 일반 로그인
public PrincipalDetails(User user) {
this.user = user;
}
// OAut 로그인
public PrincipalDetails(User user,Map<String,Object> attributes) {
this.user = user;
this.attributes = attributes;
}
- User에 Builder 생성
@Builder
public User(String username, String password,
String email, String role, String provider,
String providerId, Timestamp loginDate, Timestamp createDate) {
this.username = username;
this.password = password;
this.email = email;
this.role = role;
this.provider = provider;
this.providerId = providerId;
this.loginDate = loginDate;
this.createDate = createDate;
}
- PrincipalOauth2UserService
- Service 함수 종료시 @AuthenticationPrincipal 어노테이션이 만들어진다.
@Service
public class PrincipalOauth2UserService extends DefaultOAuth2UserService {
@Autowired
private BCryptPasswordEncoder bCryptPasswordEncoder;
@Autowired
private UserRepository userRepository;
// 구글로부터 받은 userRequest 데이터에 대한 후처리가 되는 함수
@Override
public OAuth2User loadUser(OAuth2UserRequest userRequest) throws OAuth2AuthenticationException {
// System.out.println("getClientRegistration: "+userRequest.getClientRegistration());
// System.out.println("getAccessToken: "+userRequest.getAccessToken().getTokenValue());
// System.out.println("getAttributes: "+super.loadUser(userRequest).getAttributes());
OAuth2User oAuth2User = super.loadUser(userRequest);
// oAuth2User =oAuth2User.getAttributes();
String provider = userRequest.getClientRegistration().getRegistrationId(); // google
String providerId = oAuth2User.getAttribute("sub");
String username = provider+"-"+providerId; // google_103234234234534543534
String password = bCryptPasswordEncoder.encode("겟인데어");
String email = oAuth2User.getAttribute("email");
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(providerId)
.build();
userRepository.save(userEntity);
}
return new PrincipalDetails(userEntity,oAuth2User.getAttributes());
}
}
- Controller접근
// OAuth 로긴을 해도 PrincipalDetails
// 일반 로그인을 해도 PrincipalDetails
@GetMapping("/user")
public @ResponseBody String user(@AuthenticationPrincipal PrincipalDetails principalDetails){
System.out.println("principalDetails: "+principalDetails.getUser());
return "user";
}
'SpringBoot > Security' 카테고리의 다른 글
[SpringSecurity] Form Login 인증 (0) | 2023.04.03 |
---|---|
[SpringBoot] Security 네이버 로그인 (0) | 2023.01.23 |
[SpringBoot] Security 페이스북 로그인 (security facebook login) (0) | 2023.01.23 |
[SpringBoot] Security 권한 부분 설정 (0) | 2023.01.20 |
[SpringBoot] Security 회원가입과 로그인 (0) | 2023.01.20 |