Oauth2 by Google

2024. 1. 22. 16:07Spring Boot

Oauth란 외부의 로그인 정보를 받아서 로그인을 진행하는 기능이다

2는 버전업되면서 붙었고 보안 때문에 Oauth대신 Oauth2를 써야한다

 

google을 이용하여 로그인 기능을 구현하여 보겠다

 

사전에 여러 설정을 해줘야 하는데

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

 

우선 gradle을 이용해 필요한 라이브러리를 추가해주고

 

Google Console에 접속한다

https://console.cloud.google.com/welcome?hl=ko

 

Google 클라우드 플랫폼

로그인 Google 클라우드 플랫폼으로 이동

accounts.google.com

 

 

 

 

새 프로젝트를 하나 만들어주고

 

API 및 서비스로 들어가준다

 

 

 

 

 

사용자 인증 정보에서 사용자 인증 정보 만들기를 눌러 Oauth 클라이언트 ID를 만든다

 

 

 

 

웹페이지를 만들것이니 애플리케이션 유형은 웹 애플리케이션으로 설정하고

승인할 리디렉션 URL은 Spring boot에서는 사용하는 주소 + /login/oauth2/code/google로 설정 해주면 된다

 

 

이제 생성된 ID에 들어가

 

 

ID와 비밀번호를 따로 기록한다

 

 

application.properties에 아까 기록한 ID와 비밀번호를 설정을 추가한다

또한 비밀번호는 절대 웹상에서 공개하면 안 된다

 

scope에는 구글에서 읽어올 계정 정보의 범위를 지정한다 위 예제에서는 프로필과 이메일 정보를 읽었다

 

 

 

@Configuration
@EnableWebSecurity
@RequiredArgsConstructor
public class SecurityConfig {

    @Autowired
    private CorsConfig corsConfig;
    
    @Autowired
    private CustomOAuth2Service customoAuth2Service;
    
    @Autowired
    private final jwtProvider tokenProvider;

    @Bean
    SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
        //http.addFilterBefore(new myfilter1(),  BasicAuthenticationFilter.class);
        http.authorizeHttpRequests((authorizeHttpRequests) -> authorizeHttpRequests
            .requestMatchers(new AntPathRequestMatcher("/user/data"))
            .hasRole("User")
            .anyRequest().permitAll());
      
        http.httpBasic((basic) -> basic.disable());

        http.apply(new jwtDsl(tokenProvider));
        http.apply(new sessionDsl());

        http.logout((logout) -> logout
            .logoutUrl("/user/logout/session")
            .logoutSuccessUrl("/"));

        http.sessionManagement((session) ->
            session
                .sessionCreationPolicy(SessionCreationPolicy.ALWAYS));

        http.csrf((csrf) -> csrf
            .ignoringRequestMatchers(new AntPathRequestMatcher("/form/**")));

        http.headers((headers) -> headers
            .addHeaderWriter(new XFrameOptionsHeaderWriter(
                XFrameOptionsHeaderWriter.XFrameOptionsMode.SAMEORIGIN)));

        http.oauth2Login((oauth) -> oauth
            .loginPage("/")
            .userInfoEndpoint((userInfoEndpoint) -> userInfoEndpoint
                .userService(customoAuth2Service)));
                
        return http.build();
    }

 

이제 SecurityFilterChain에 설정을 등록한다

 

 

CustomOAuth2Service.java

import java.util.Optional;

import org.springframework.security.oauth2.client.userinfo.DefaultOAuth2UserService;
import org.springframework.security.oauth2.client.userinfo.OAuth2UserRequest;
import org.springframework.security.oauth2.client.userinfo.OAuth2UserService;
import org.springframework.security.oauth2.core.OAuth2AuthenticationException;
import org.springframework.security.oauth2.core.user.OAuth2User;
import org.springframework.stereotype.Service;

import com.example.demo.customUserDetail.CustomDetail;
import com.example.demo.user.user;
import com.example.demo.user.user_repository;

import lombok.RequiredArgsConstructor;

@Service
@RequiredArgsConstructor
public class CustomOAuth2Service implements OAuth2UserService<OAuth2UserRequest, OAuth2User>{
    private final user_repository repo;
    

    @Override
    public OAuth2User loadUser(OAuth2UserRequest userRequest) throws OAuth2AuthenticationException {
        System.out.println("userRequest : " + userRequest);
        // System.out.println("access token : " + userRequest.getAccessToken());
        System.out.println("client Registration : " + userRequest.getClientRegistration());
        OAuth2UserService<OAuth2UserRequest, OAuth2User> delegate = new DefaultOAuth2UserService();
        System.out.println("user : " + delegate.loadUser(userRequest));
        oauth2Info info = new googleInfo(delegate.loadUser(userRequest).getAttributes());

        Optional<user> userOp = repo.findOneByProviderIdAndProvider(info.getProviderId(), info.getProvider());
        if(info.getProvider().equals("google")) {
            System.out.println("google login");
        }
        user user;
        if(!userOp.isPresent()) {
            user = new user();
            user.setProvider(info.getProvider());
            user.setProviderId(info.getProviderId());
            user.setName(info.getName());
            user.setEmail(info.getEmail());
            repo.save(user);
        }
        else {
            user = userOp.get();
        }
        return new CustomDetail(user);
    }
}

 

여러 구글 말고도 네이버 카카오등 여러 곳에서 인증 정보를 읽을 수 있기 때문에 google만 구현했지만 정보는 따로 클래스를 만들어서 읽어 주었다

 

또한 로그인 진행한 정보에서 정보를 읽어 들여서 데이터 베이스에 유저 정보를 저장하였다

 

 

oauth2Info.java

public interface oauth2Info {
    String getName();
    String getProvider();
    String getProviderId();
    String getEmail();
}

 

 

googleInfo.java

import java.util.Map;

public class googleInfo implements oauth2Info{

    private Map<String, Object> attributes;

    googleInfo(Map<String, Object> attributes) {
        this.attributes = attributes;
    }
    
    @Override
    public String getProviderId() {
        return (String) attributes.get("sub");
    }

    @Override
    public String getName() {
        return (String) attributes.get("name");
    }

    @Override
    public String getEmail() {
        return (String) attributes.get("email");
    }

	@Override
	public String getProvider() {
		return "google";
	}
    
}

 

 

이제 

https://localhost:5000/oauth2/authorization/google로 요청을 보내면 

 

 

구글을 통해 로그인을 진행 할 수 있다

'Spring Boot' 카테고리의 다른 글

Redis  (0) 2024.01.28
RestController  (0) 2024.01.28
Docker Container에 JAR 이미지 돌리기  (0) 2024.01.20
MongoDB Reference  (1) 2024.01.19
Https  (0) 2024.01.12