Java Spring Boot 007-4 | OAuth2 & JWT

Yunny.Log ·2022년 3월 14일
0

Spring Boot

목록 보기
37/80
post-thumbnail

OAuth2 & JWT

Social Login의 실체

1) single sign up

  • 하나의 로그인 서비스로 다양한 도메인 사용 가능한 것

OAuth2

  • 사용자의 정보를 데려오는 과정이라고 보아도 된다

  • redirect로 a 사이트가 아니라 네이버 사이트에 가서 로그인을 하게 한다.

  • 로그인 성공하면 a 사이트로 다시 돌아가야 하니깐 네이버에서 네이버에 지정된 적절한 callback url(a 사이트 로그인 성공 페이지 혹은 정보 받는 페이지 ..)

  • 네이버 설정 이후 build.gradle 추가

	implementation 'org.springframework.boot:spring-boot-starter-oauth2-client'
  • yml

spring:
  datasource:
    url: jdbc:h2:mem:testdb
    driver-class-name: org.h2.Driver
    username: sa
    password: password
  jpa:
    database: h2
    database-platform: org.hibernate.dialect.H2Dialect
  security:
    oauth2:
      client:
        registration:
          naver: # 원하는 서비스 
            client-id: <your_client_id>
            client-secret: <your_client_secret>
            redirect-uri: "{baseUrl}/{action}/oauth2/code/{registrationId}"
            # 처음에 요청 보내고 다시 access token 어디로 전달할 지에 대한
            authorization-grant-type: authorization_code 
            scope: email
            client-name: Naver
        provider:
          naver:
            authorization-uri: https://nid.naver.com/oauth2.0/authorize
            token-uri: https://nid.naver.com/oauth2.0/token
            user-info-uri: https://openapi.naver.com/v1/nid/me
            user-name-attribute: response
            
            #사용자 정보가 들어올 때 
            #json 응답으로 돌아오면 적절 키값 (ex 카카오)
            
            #네이버는 response {.. } 형태로 돌아옴

NaverService

    @Override
    public OAuth2User loadUser(OAuth2UserRequest userRequest) throws OAuth2AuthenticationException {
        OAuth2UserService<OAuth2UserRequest, OAuth2User> delegate = new DefaultOAuth2UserService();
        OAuth2User oAuth2User = delegate.loadUser(userRequest);
        //사용자의 정보가 들어올 객체
        //네이버에서 사용자의 정보를 request 요청을 받는다

        String registrationId = userRequest.getClientRegistration().getRegistrationId();
        String userNameAttributeName = userRequest.getClientRegistration().getProviderDetails().getUserInfoEndpoint().getUserNameAttributeName();

security

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http
                .authorizeRequests()
                .antMatchers(
                        "/home/**",
                        "/user/signup/**",
                        "/",
                        "/css/**",
                        "/images/**",
                        "/js/**"
                )
                    .anonymous()
                    .anyRequest()
                    .authenticated()
                .and()
                    .formLogin()
                    .loginPage("/user/login")
                    .defaultSuccessUrl("/home")
                    .permitAll()
                .and()
                    .oauth2Login()//네이버에서 로그인되면 우리에서도 로그인된 것으로 처리
                        .userInfoEndpoint()
                        .userService(this.oAuth2UserService) //네이버에서의 유저정보가 우리 유저정보에도 저장이 된다
                    .and()
                    .defaultSuccessUrl("/home")
                .and()
                    .logout()
                    .logoutUrl("/user/logout")
                    .logoutSuccessUrl("/home")
                    .deleteCookies("JSEESIONID")
                    .invalidateHttpSession(true)
                    .permitAll()

                .and()
                .oauth2Client()
        ;
    }

=> email을 추가적으로 받아옴

@Service
public class NaverOAuth2Service implements OAuth2UserService<OAuth2UserRequest, OAuth2User> {
    private final UserRepository userRepository;

    public NaverOAuth2Service(
            @Autowired
                    UserRepository userRepository,
            @Autowired
                    HttpSession httpSession
    ) {
        this.userRepository = userRepository;
    }

    @Override
    public OAuth2User loadUser(OAuth2UserRequest userRequest) throws OAuth2AuthenticationException {
        OAuth2UserService<OAuth2UserRequest, OAuth2User> delegate = new DefaultOAuth2UserService();
        OAuth2User oAuth2User = delegate.loadUser(userRequest);
        //사용자의 정보가 들어올 객체
        //네이버에서 사용자의 정보를 request 요청을 받는다

        String registrationId = userRequest.getClientRegistration().getRegistrationId();
        String userNameAttributeName = userRequest.getClientRegistration().getProviderDetails().getUserInfoEndpoint().getUserNameAttributeName();

        Map<?, ?> refinedAttributes = (Map<?, ?>) oAuth2User.getAttributes().get("response");
        UserEntity user = new UserEntity();
        user.setUsername((String) refinedAttributes.get("email"));

        return new DefaultOAuth2User(
                Collections.singleton(new SimpleGrantedAuthority("ROLE_USER")), //권한 설정해주기
                (Map<String, Object>) refinedAttributes,
                "email");
    }
}

Json Web Token

  • 액세스 토큰, 리프레시 토큰으로 사용자를 검증하는 과정
  • 리프레시는 액세스의 유효성을 보장해주기 위해서 존재함

(+) 네이버 response


{
  "resultcode": "00",
  "message": "success",
  "response": {
    "email": "openapi@naver.com",
    "nickname": "OpenAPI",
    "profile_image": "https://ssl.pstatic.net/static/pwe/address/nodata_33x33.gif",
    "age": "40-49",
    "gender": "F",
    "id": "32742776",
    "name": "오픈 API",
    "birthday": "10-01",
    "birthyear": "1900",
    "mobile": "010-0000-0000"
  }
}

0개의 댓글