2.1 구글 로그인 준비
- 구글 api 콘솔
- 새프로젝트 만들기
- 프로젝트를 만들면 프로젝트를 통해 구글 로그인이 가능하다.
- 동의 화면: 외부 체크
- 사용자 인증 정보
- oauth 클라이언트
- 승인된 리다이렉션 URI: http://localhost:8080/login/oauth2/code/google
- (코드를 받을 수 있는 주소) oauth2 까지는 고정이다.
- 구글 로그인이 완료 되고 나면 구글 서버에서 나한테 인증 완료됐다는 코드(?)를 돌려준다.
- 우리는 이 코드를 통해 엑세스 토큰을 요청한다.
- 엑세스 토큰을 통해 구글 서버에 사용자의 개인 정보를 요청할 수 있다.
- 라이브러리 설치
- yml 파일에 다음과 같이 추가한다.
<hide/>
spring:
security:
oauth2:
client:
registration:
google:
client-id: "생성된 클라이언트 ID"
client-secret: "생성된 클라이언트 패스워드"
scope:
- email
- profile
Note) 실행 결과
- login()
- 아래 페이지에서 구글 로그인을 누르면 404 에러가 뜬다. (해당 주소에 매핑된 페이지가 없다는 뜻이다.)
2.2 구글 회원 프로필 정보 받아보기
- 구글 로그인이 완료된 다음 후 처리는 어떻게 해야할까?
- 코드 받기 (인증 완료)
- 액세스 토큰 받기 (사용자 정보에 접근할 권한이 생긴다.)
- 권한을 통해 사용자 프로필 정보를 가져온다.
- 정보를 토대로 회원 가입을 자동으로 진행시키거나 또는 필요한 정보를 추가적으로 입력받은 다음 가입시킬 수 있다.
- 구글 로그인이 완료되면 코드가 아닌 엑세스 토큰 + 사용자의 프로필 정보를 한 번에 받는다.
- 보안 설정 파일
<hide/>
@Override
protected void configure(HttpSecurity http) throws Exception {
http.csrf().disable();
http.authorizeRequests()
.antMatchers("/user/**").authenticated()
.antMatchers("/manager/**").access("hasRole('ROLE_ADMIN') or hasRole('ROLE_MANAGER')")
.antMatchers("/admin/**").access("hasRole('ROLE_ADMIN')")
.anyRequest().permitAll() // 다른 요청은 전부 허용한다.
.and()
.formLogin()
.loginPage("/loginForm")
.loginProcessingUrl("/login")
.defaultSuccessUrl("/")
.and()
.oauth2Login()
.loginPage("/loginForm")
.userInfoEndpoint()
.userService(null);
}
- PrincipalOauth2UserService
- loadUser()를 오버라이드하는데 여기서 구글 로그인에 대한 후 처리를 한다.
- 코드 없이 엑세스 토큰과 사용자의 프로필 정보가 userRequest로 반환된다.
- getClientRegistration: 클라이언트 ID, 비밀 번호
- 어떤 oauth로 로그인했는지 확인이 가능하다.
- getAccessToken: 엑세스 토큰
- getAttributes: 사용자에 대한 정보
<hide/>
@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());
System.out.println("getAttributes: " + super.loadUser(userRequest).getAttributes());
return super.loadUser(userRequest);
}
}
Note) 실행 결과
- 이미 사용자 정보를 받았기 때문에 토큰이 필요 없다.
- sub는 구글의 데이터베이스에서 내 id의 pk 같은 값이다.
<hide/>
getClientRegistration: ClientRegistration{registrationId='google', clientId="클라이언트 ID", clientSecret="클라이언트 비번", 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@74290e0c, clientName='Google'}
getAccessToken: org.springframework.security.oauth2.core.OAuth2AccessToken@1386af83
getAttributes: {sub="내 구글 id의 pk 느낌", name="사용자 full name", given_name="first name", family_name="성", picture="프로필 사진 이미지 링크", email="이메일 주소", email_verified=true, locale=ko}
Ex) 위에서 받은 정보 활용하기
- 아래와 같이 설정한다.
- username = "google_" + sub
- password = "암호화(겟인데어)"
- 이 비번으로 로그인하는게 아니라서 null만 아니면 되고 어떤 값이든 상관없다.
- email: email
- role: "ROLE_USER"
- 일반 사용자인지 OAUTH2 사용자인지 구분하려면?
- user에 필드 추가 => provider, providerId
- 위 정보를 가지고 강제로 회원 가입 시킬 예정이다.
2.3 Authentication객체가 가질 수 있는 2가지 타입
oauth를 통한 화원 가입 과정
- 구글 로그인 클릭 => 구글 로그인 창 => 로그인 완료 => code를 반환(oauth-client) => access token 요청 ..... UserRequest
- loadUser()를 이용해서 구글로부터 회원의 프로필을 받는다.
'Spring Framework > [인프런] Spring Security & OAuth 2.0 & JWT' 카테고리의 다른 글
Chapter 03. 스프링 시큐리티 웹 보안 이해 (0) | 2022.12.05 |
---|---|
Chapter 01. 스프링 시큐리티(Spring Security) 기본 (0) | 2022.10.14 |