Coding History/project

OAuto2 인증 받아 구글 로그인 구현중

BlackBirdIT 2024. 9. 9. 11:22

이제 진짜 본론으로 드디어 도달할 수 있게 되었다.

일단 내가 생각했을 때, 구글로그인을 구현해가는 방법이나 순서를 생각의 흐름대로 나열해보자.

Thinking Flow

난 로컬 유저와 소셜유저를 아예 나눌 생각이다. 그래서 이메일로 로그인하게끔 만든거고, 테이블의 소셜 두개를 따로 둬서 해당 두개의 값이 다 null이라면 로컬인거고 둘 중 하나가 채워져있다면 소셜로그인인것. 두개는 스포티파이와 구글이다. 일단 난 구글에 집중해야되니, 스포티파이는 빼놓자고.

그렇다면 어떻게 해야할까. 소셜로그인의 작동 방식은 조금만 생각해도 유추가 된다. 일단은 로그인 시도, 일치하는 정보가 없다? 그러면 바로 회원가입을 자동으로 처리 이후에 다시 로그인을 시켜준다. 이게 일반적인 소셜로그인의 방식일 것이다.

그럼 이제 대충 그림은 그려진다. 핵심은 대충 파악이 됐으니 가장먼저 해결해야될 문제부터 다시보자.

  1. firebase에서 유저 정보를 끌어와야한다. 이걸 어떻게 하는가? 에 대한 문제
  2. 이젠 토큰이라는 개념을 사용해야되는데 이건 어떻게 사용하고 관리하는가? 에 대한 문제.

일단은 해당 문제에 집중하면서 구현을 시작해보자.

Firebase Admin SDK 설정

부터 해야된다고 한다. 공홈에 있다. 이걸 참고하장.

사실 읽어도 뭔지 잘 파악 안된다. 여태 했던 것 처럼 뭐 머리 박으면서 해봐야지. 일단 바로 사용해보자.

<dependency>
  <groupId>com.google.firebase</groupId>
  <artifactId>firebase-admin</artifactId>
  <version>9.2.0</version>
</dependency>

의존성 부터 추가 하랜다. 추가하도록하자. 아 이미 했구나! 생각해보니까 구글 로그인 정보를 firebase에 보내는 걸 성공했었다.

여기 있네 저번에 테스트 했던 계정. 그럼 뭐다? 이 데이터 끌어오는 로직을 테스트 해보면 된다.

일단은 토큰은 치워두고 정보를 끌어오는 것 부터 테스트해보자.

    public UserRecord getUserByEmail(String email) throws FirebaseAuthException {
        return FirebaseAuth.getInstance().getUserByEmail(email);
    }

firebaseConfig 클래스에 해당 메서드 만들어뒀고,

member에 다 때려박을까 했는데 아무래도 클래스를 나눠놓는게 추후에 편할 것 같으니까 firebase 컨트롤러와 서비스는 따로 만들자.

@RestController
public class FirebaseController {

    private final FirebaseUserService firebaseUserService;

    @Autowired
    public FirebaseController(FirebaseUserService firebaseUserService) {
        this.firebaseUserService = firebaseUserService;
    }

    @GetMapping("/firebaseUser")
    public String getFirebaseUserByEmail(@RequestParam String email) {
        try {
            UserRecord userRecord = firebaseUserService.getUserByEmail(email);
            return "User found: " + userRecord.getEmail();
        } catch (FirebaseAuthException e) {
            return "Error: " + e.getMessage();
        }
    }
}

@Service
public class FirebaseUserService {

    // 이메일로 Firebase에서 사용자 정보 가져오기
    public UserRecord getUserByEmail(String email) throws FirebaseAuthException {
        return FirebaseAuth.getInstance().getUserByEmail(email);
    }

    // UID로 사용자 정보 가져오기
    public UserRecord getUserByUid(String uid) throws FirebaseAuthException {
        return FirebaseAuth.getInstance().getUser(uid);
    }

    // Firebase에 새 사용자 추가
    public void createUser(String email, String password) throws FirebaseAuthException {
        UserRecord.CreateRequest request = new UserRecord.CreateRequest()
                .setEmail(email)
                .setPassword(password);
        UserRecord userRecord = FirebaseAuth.getInstance().createUser(request);
        System.out.println("Successfully created new user: " + userRecord.getUid());
    }
}

일단은 요래 만들었다.

로그인 시도를 하면 테스트가 될 것 같긴한데, 생각해보니까 또 시큐리티가 막는거아냐..?
토큰 부터 했어야했나 갑자기 후회되네.

우선 그냥 테스트 해봤는데 테스트는 일단 생기는 오류들부터 쳐내가며 진행했다. 엑세스 차단됨 이라는 문구와 오류코드 400 redirect_uri_mismatch라는 새 창이 뜨면서 계속 막혔다. 그래서 알아봤는데 Google Cloud Console에서 좀 할 게 더 남았던 것 같다. 바로 가서 확인해보자.

Google Cloud Console에 로그인한 후, API 및 서비스 > 자격 증명(Credentials)으로 이동한다.


그렇게 리디렉션을 추가해줬는데, 여기서 form 태그에서 submit해서 전송하는 url을 줘야햐는데 로그인 페이지를 줘놓고 왜 안되는지 한참 고민했다. 꼭 본인이 구글 로그인을 하겠다고 지정한 곳을 리디렉션으로 주자. 그러니까 form태그의 action 값을 주면 된다.

암튼 다 설정해주니까 이런 오류가 발생했다.

저게 정의되지 않았다고 하는데 난 저런걸 만들지 않았으니까 firebase에 관련된 패키지 코드 같은데 일단 정보를 모아보자.

지피티 말로는 일단 내가 만든 함수가 제대로 작동했는가 확인하라고 해서 브라우저 콘솔에 찍어보니까 메서드는 제대로 작동한 것 같다. (아래 사진)

버전 이슈가 있을 수도 있대서 firebase 버전도 체크해봤는데 제일 최신 버전이니까 이 문제는 아닐테고,

일단 불러오지 못한다는거 콘솔에 찍어보니까

못찾아오는게 확실해졌다. 버전을 낮춰볼까? 최신버전 정보가 많지 않아서 힘들다.

아니다 버전 낮추는건 존심 상한다 끝까지 가본다. 설정 관련된 파일을 죄다 뒤져봤는데 설정에는 문제가 될 요지느 없는 것 같다. 내가 짠 firebase와 관련되어있는 코드를 우선 다 살펴보자.

콘솔로그를 아예 index.js에 찍어보고 이후에 브라우저에서 찍어봤다.

처음에 진입 단계에서는 잘 불러오던게 브라우저에서 참조하지 않고 소실되는 걸 발견.

그래서 브라우저에 접속할 때, 초기화 하고, 다시 참조하게끔 index.js를 수정했다.

이제서야 다시 뜬다..

근데 엑세스는 여전히 차단되어있네?

redirect_uri을 정확하게 파악할 필요가 생겼다.

cors 설정이 필요하다고 한다.

cors 설정을 위해 기존 MyWebMVCConfigurer클래스 안에

    // CORS 설정 추가
    @Override
    public void addCorsMappings(CorsRegistry registry) {
        registry.addMapping("/**") // 모든 경로에 대해 CORS 허용
                .allowedOrigins("http://localhost:8081") // 허용할 도메인
                .allowedMethods("GET", "POST", "PUT", "DELETE") // 허용할 HTTP 메서드
                .allowedHeaders("*") // 허용할 헤더
                .allowCredentials(true); // 자격증명(쿠키, 인증 정보) 허용
    }

이렇게 작성해주고, 시큐리티에서도 cors를 포함 시켜주었다.
하고나서 https://YOUR-PROJECT.firebaseapp.com/__/auth/handler 이렇게 설정을 해주니까.

드디어 이렇게 생성됐다!

그러고 기쁜 마음으로 (맨 위가 내가 firebase에 전송시킨 계정이다.) 클릭했더니,

또 엑세스 오류다. 이제 슬슬 대노 단계에 진입할 것 만 같이 아찔하네..

설정에서 이 주소까지 포함시켜보자고..

포함시키고 난 다음 로그인을 드디어 성공했다.

일단 성공했으니 다음 목표

  • 로그인 성공했으니까 이 데이터를 끌어와서 만들어둔 firebase 컨트롤러로 매핑 시켜야함.
  • 이후 서비스로 접근해 유저 데이터를 뽑아오고 DB에 저장시켜야함.

글은 끊어 가겠다, 이 포스팅 너무나 긴 여정이였다..