Spring Framework/[인프런] Spring Security & OAuth 2.0 & JWT

Chapter 02. 스프링 시큐리티 OAuth 2.0

계란💕 2022. 10. 14. 15:36

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 구글 회원 프로필 정보 받아보기

 

  • 구글 로그인이 완료된 다음 후 처리는 어떻게 해야할까?
    1. 코드 받기 (인증 완료)
    2. 액세스 토큰 받기 (사용자 정보에 접근할 권한이 생긴다.)
    3. 권한을 통해 사용자 프로필 정보를 가져온다.
    4. 정보를 토대로 회원 가입을 자동으로 진행시키거나 또는 필요한 정보를 추가적으로 입력받은 다음 가입시킬 수 있다.
  • 구글 로그인이 완료되면 코드가 아닌 엑세스 토큰 + 사용자의 프로필 정보를 한 번에 받는다.
  • 보안 설정 파일
<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()를 이용해서 구글로부터 회원의 프로필을 받는다.

 

 

 

 

 

 

 

출처 - https://www.inflearn.com/course/%EC%8A%A4%ED%94%84%EB%A7%81%EB%B6%80%ED%8A%B8-%EC%8B%9C%ED%81%90%EB%A6%AC%ED%8B%B0/dashboard

 

[무료] 스프링부트 시큐리티 & JWT 강의 - 인프런 | 강의

스프링부트 시큐리티에 대한 개념이 잡힙니다., - 강의 소개 | 인프런...

www.inflearn.com