CRUD 실습

OAuth 2.0으로 구글로그인 적용하기 [탐구/기록]

rexondex 2024. 9. 30. 18:18

 

OAuth 2.0 (Open Authorization 2.0)인증을 위한 개방형 표준 프로토콜입니다.

이 프로토콜은 제3자 프로그램이 리소스 소유자를 대신하여 리소스 서버에서 제공하는 자원에 대한 접근 권한을 위임받는 방식을 제공합니다.

 

곧 구현하려는 기능은 소셜 로그인을 통해 현재 진행중인 프로젝트에 로그인 기능을 구현하는 것입니다.

 

 

1. 사용자가 웹에 접근했을 때

2. 로그인이 필요한 곳이나 특정 페이지에서 로그인화면으로 이동(구글 로그인 등)

3. 소셜 로그인 인증 후 다시 원래 접근했던 곳이나 로그인이 필요했던 기능으로 리다이렉트

 

를 구현하는 것이 목표입니다.​​

 

현재 디렉토리 구조

 

gradle에서 oauth2 관련 의존성을 추가하고,

config 패키지와 oauth 패키지를 생성하여 클래스들을 구성하였습니다.

 

dependencies {
    //...
	implementation 'org.springframework.boot:spring-boot-starter-security'
	implementation 'org.springframework.security:spring-security-oauth2-client'
	implementation 'org.springframework.security:spring-security-oauth2-jose'
}

 

 

SecurityConfig 에서는 스프링 시큐리티 기능인 특정 리소스(URI) 에 대한 접근 제한 및 권한 설정에 관한 내용이 포함되어 있고, SessionMember 클래스에는 현재 로그인한 유저(멤버)의 정보 및 세션 관리를 위한 설정이 포함되어 있습니다.

 

// 3가지의 커스텀 OAuth2 클래스를 생성했습니다.

public class CustomOAuth2User implements OAuth2User {...}

public class CustomOAuth2UserService extends DefaultOAuth2UserService {...}

public class CustomOAuth2AuthenticationSuccessHandler extends SimpleUrlAuthenticationSuccessHandler {...}

 

위 클래스들이 각각 상속 및 확장하여 필요에 맞게 메소드 오버라이딩 하도록 구성하였습니다.​​

 

 

구글 계정을 선택할 수 있는 인증화면

 

 

첫번째로 ' localhost:8080/main ' 으로 접속했을 때 /main 으로 접근하기 전에 "계정 선택" 화면으로 무조건 이동하게 되어있습니다.

 

지금은 웹어플리케이션에 접근하자마자 꼭 계정을 선택하게 되어 있지만 특정 URI에 접근할때나 로그인 버튼을 눌렀을 때, 또는 사용자정보 및 권한이 필요한 곳에서 적용되게 할 수 있다고 합니다.​​

 

로그인 액세스 허용 및 계속

 

 

계정을 선택하면 (프로젝트명)가 google 계정에 대해 액세스 하려고 하는데 계속할건지 물어봅니다.

현재 사용자 정보로는 " 프로필 사진, 사용자 이름, 사용자 이메일 "3가지를 필요로 합니다​​

 

로그인 후 접속된 /main URI

 

이제 /main 으로 로그인 후 들어온 것이며 로그인을 했기 때문에 현재 페이지에서 사용자 정보를 가지고 있습니다.

예를 들어 게시글에 관련된 기능 같은 경우 게시글 (쓰기/수정/삭제)를 할때 이 사용자 정보를 이용해서 CRUD 작업을 수행할 수 있을 것입니다.

사용자 정보를 가져오는 과정은 컨트롤러 레이어에서 @AuthenticationPrincipal 이라는 어노테이션을 사용하면 현재 인증된 사용자의 정보를 가져올 수 있다고 합니다.

 

 

// 사용자 정보를 가져오는 예제 코드

import org.springframework.security.core.annotation.AuthenticationPrincipal;
import org.springframework.security.oauth2.core.user.OAuth2User;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class UserController {
    @GetMapping("/user")
    public String getUserInfo(@AuthenticationPrincipal OAuth2User principal) {
        return "User info: " + principal.getAttributes();
    }
}

 

 

/main 에서 가져왔었던 게시물 정보

 

 

POST 테이블은 게시물 하나하나가 가진 데이터를 가지고 있는데, 이전에는 좋아요/태그 등을 구분하지 않은 상태에서 뒤섞여 있는 경향이 강했다면, 지금은 테이블을 분리하여 더 명확하게 구성하려고 했습니다.

테이블 설계와 JpaRepository 를 설정한 로직에 대해서는 다른 글에서 한번 더 알아보겠습니다.