Springboot Security + Oauth2 구글 로그인 구현

Juice🌱·2024년 2월 5일
1

SpringBoot

목록 보기
6/7
post-thumbnail

SpringBoot Security의 구글 로그인 구현만을 위한 velog입니다.

인증(Authentication)과 인가(Authorization)

인증(Authentication) : 서비스를 사용하려는 유저의 신원을 확인하는 것
인가(Authorization) : Authorize(권한 부여). 말 그대로 권한을 확인하는 것

학교 웹사이트에서 공지를 보고 싶은 🙋🏻‍♂️ -> 웹사이트 들어가기 위해 학교 학생이메일로 로그인 하는 것이 인증(Authentication), 인증을 한 후 학교에서 해당 학생의 수업 정보 등 조회할 수 있는 권한을 확인하는 것이 인가(Authorization) 입니다.

Spring Security

Spring 어플리케이션의 보안(인증과 인가)를 담당하는 스프링에서 제공하는 Framework입니다.

security의 특징

  • Filter 기반으로 작동 -> MVC와 분리되어 동작한다
  • Bean으로 등록 가능 -> 스프링의 의존성 주입(DI) 메커니즘 활용

Oauth로 구글 로그인하고 DB에 저장하는 과정

구글 cloud cloud console 설정

google cloud console에 들어가서 프로젝트 생성해주고 OAuth Client ID를 만들어주세요!

어플리케이션 유형에 여러 종류가 있는데 JAVA로 구글 Oauth 로그인 구현한다 ?
->무조건 웹 어플리케이션 선택
kotilin으로 안드로이드 앱 만든다, swift로 iOS 앱 만들거니까 android 혹은 iOS 골라야지? 하면 큰일납니다! 여러분이 kotilin 혹은 swift를 이용해 자체적으로 google sign in 을 구현한다면 안드로이드 / iOS를 골라야 하지만, 그게 아니라 로그인 view로만 사용하고 스프링부트에서 로그인 구현하는거면 무조건 웹 어플리케이션 선택하셔야 합니다.

승인되 redirect uri

저의 다른 velog에도 정리되어 있는데 자세하게 보고 싶다? -> https://velog.io/@juice/SpringBoot-Oauth2-Google-LoginOauth2를-이용한-구글-로그인

승인된 리디렉션 URI는 구글 로그인 폼 주소가 아니라 유저가 로그인을 성공적으로 마치면 구글 서버에서 저희의 서버로 유저가 인증 되었다는 코드를 돌려주고, 저희는 이 코드를 가지고 유저의 정보에 접근,획득할 수 있는 access token을 얻는겁니다.

따라서 승인된 리디렉션 URI는? 코드를 얻을 수 있는 주소!!

스프링부트 프로젝트 생성

Mysql Schema 생성 + 연결

application.properties

spring.security.oauth2.client.registration.google.client-id=클라이언트 ID
spring.security.oauth2.client.registration.google.client-secret=클라이언트 보안 비밀
spring.security.oauth2.client.registration.google.scope=profile,email

여기까지 하면 코드 이외의 기본 설정들을 얼추 다 끝났습니다!

로그인 구현

로그인 UI 만들기 (프런트 없이 mustache 이용)

resources/templates/loginForm.html 이라는 파일 생성

<!DOCTYPE html>
<html lang="en">
<head>
   <meta charset="UTF-8">
   <title>LoginForm</title>
</head>
<body>
<form action="/login" method="post">
   <input type="text" name="username" placeholder="Username"> <br />
   <input type="password" name="password" placeholder="Password"> <br />
   <button type="submit">Login</button>
</form>
<a href="/oauth2/authorization/google">구글 로그인</a>
<a href="/joinForm">회원가입 아직 안하셨나요?</a>
</body>
</html>

WebMvcConfig.java

main/java안에 config라는 폴더 만들고 그안에 WebMvcConfig라는 자바 파일 만들어 줍니다. 이 파일은 mustache로 view 렌더링 하기위해 만들어주는 것입니다.

@Configuration
public class WebMvcConfig implements WebMvcConfigurer {
    @Override
    public void configureViewResolvers(ViewResolverRegistry registry){
        MustacheViewResolver resolver = new MustacheViewResolver();
        resolver.setCharset("UTF-8");
        resolver.setContentType("text/html;charset=UTF-8");
        resolver.setPrefix("classpath:/templates/");
        resolver.setSuffix(".html");
        registry.viewResolver(resolver);
    }
}

mustache가 .mustache로 되어 있는데, 이걸 .html로 view를 바꿔준다고 생각하시면 됩니다

SecurityConfig.java

우리 어플리케이션에서 하는 구글 로그인 관련 보안을 모두 관리하는 파일입니다.

@Configuration
@EnableWebSecurity
@EnableMethodSecurity(securedEnabled = true)
@RequiredArgsConstructor
public class SecurityConfig {

    private final PrincipalOauth2UserService principalOauth2UserService;
    private final CorsConfig corsConfig;

    @Bean
    public SecurityFilterChain filterChain(HttpSecurity http) throws Exception{
        http.csrf(AbstractHttpConfigurer::disable);
        http.addFilter(corsConfig.corsFilter());
        http.authorizeHttpRequests(au -> au.anyRequest().permitAll());
        http.oauth2Login(
                oauth -> oauth.loginPage("/loginForm")
                        .defaultSuccessUrl("/home")
                        .userInfoEndpoint()
                        .userService(principalOauth2UserService)
        );
        return http.build();
    }
}

사용자가 구글 로그인했을 떄 우리가 추가적으로 accesscode 요청하고 프로필 요청할 필요없이 한번에 유저의 프로필 가져다주는 굉장히 편리한 oauth2client 라이브러리의 userInfoEndpoint와 userService를 사용할건데, 아직 이와 관련해서 만든것이 아무것도 없기때문에 null 넣어놓고 넘어갑니다.

oauth/PrincipalOauth2UserService

oauth 라는 폴더 만들고 그 안에 service 그리고 그안에 PrincipalOauth2UserService.java라는 파일 만들어줍니다.

@Service
@Slf4j
public class PrincipalOauth2UserService extends DefaultOAuth2UserService {
// loadUser는 구글에서 유저 프로필 받아옴
    @Override
    public OAuth2User loadUser(OAuth2UserRequest oAuth2UserRequest) throws OAuth2AuthenticationException{
        log.info("google 에서 받아온 userRequest : " + oAuth2UserRequest );
        OAuth2User oAuth2User = super.loadUser(oAuth2UserRequest);
        log.info("oauth에서 받아온 정보 : "+ oAuth2User.getAttributes());
        return super.loadUser(oAuth2UserRequest);
    }
}

LoginController.java

url로 요청이 올테니 요청을 처리할 controller도 만들어 줘야겠죠? oauth 폴더 안에 LoginController.java라는 파일을 만들어 주고 아까 우리가 만든 loginForm을 보여줍시다

@Controller
public class LoginController {
    @GetMapping("/loginForm")
    public String login(){
        return "loginForm";
    }
}

하고 서버 작동시키고 localhost:8080/oauth2/authorization/google 로 들어간다면??

구글 로그인 하는 폼 잘 나옵니다!! 로그인 한다면??

뭐야? 🥶

이게 앱이 만약 test단계여서 허용된 user들만 로그인 할 수 있다는 뜻이에요. 그래서 oauth 동의화면 탭에 가서 테스트 사용자에 가서 자기가 테스트할 때 사용할 이메일을 추가해주고 다시 한번 해봅시다.

🔨 추가추가

그러면 저희가 로그인 성공했을 떄 이동하게 만든 url인 /home에 이동하는 것 확인할 수 있고, 콘솔에도 잘 찍힌걸 볼 수 있습니다. 참고로 /home은 만든게 없으니 404 에러 나오는게 당연합니다?
⛔️ 404 Error? -> page를 찾을 수 없다는 에러. 서버와 관련된 것 x

PrincipalOauth2UserService

이제 남은거는 받아온 userRequest에서 원하는 정보 추출해서 여러분들의 DB에 넣으시면 끝입니다! 이건 각 서비스 목적마다 저장하는게 달라서 따로 구현하지는 않겠습니다.

CorsConfig.java

제가 올린 SecurityConfig에 CorsConfig라고 또다른 Bean으로 등록된 객체가 있었는데 이게 뭐냐면 프런트엔드와 협업할 때 CORs정책이라고 저희는 java로 만들었는데, react js로 만든 프런트엔드에게 request 보내는 권한을
주는것입니다.

위치는 SecurityConfig와 똑같은 폴더 안에 CorsConfig.java라는 파일 만들고 추가하시면 끝입니다.

@Configuration
public class CorsConfig {
    @Bean
    public CorsFilter corsFilter(){
        UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
        CorsConfiguration config = new CorsConfiguration();
        config.setAllowCredentials(true); //frontEnd에서 axios로 처리 가능하게 만들겠다
        config.addAllowedOrigin("*"); //모든 ip에 응답을 허용하겠다
        config.addAllowedHeader("*"); //모든 header에 응답을 허용하겠다
        config.addAllowedMethod("*"); //모든 post,get,put,delete,patch 요청을 허용하겠다
        source.registerCorsConfiguration("*", config); //api로 들어오는 모든 요청은 이 config를 따르겠다
        return new CorsFilter(source);
    }
}
profile
선한 영향력으로 세상을 변화시키는 새싹개발자

0개의 댓글

관련 채용 정보