Coding History/project

스포티파이 API 적용하기 시작! (로그인 부터)

BlackBirdIT 2024. 9. 19. 23:13

spotify API는 내가 예전에 통 번역해서(GPT 시켜서) 업로드 해 놓았다. 그거 보면서 하면 됨.

우선 해당 사이트 가입해서 클라이언트 ID와 비밀번호 발급부터 받아보자.

난 일단 이렇게 제출해서 받아냈다.

이제 프로젝트에 연결시켜보자.

우선 저번에 JWT할 때 환경변수는 잘 안먹는다는 것을 알았기 때문에 프로젝트 상에서 변수로 만들어서 저장해주고.
(하는 김에 구글도 변수 처리 해줬다.)

  security:
    oauth2:
      client:
        registration:
          google:
            client-id: 742772456036-mvhbsvmdcmv0mjtev6sjqjjdg3t3tcfv.apps.googleusercontent.com  # 구글 클라이언트 ID
            client-secret: ${GOOGLE_CLIENT_SECRET}  # 구글 클라이언트 비밀번호
            scope: profile, email
            redirect-uri: "{baseUrl}/login/oauth2/code/{registrationId}"
            client-name: Google
          spotify:
            client-id: ${SPOTIFY_CLIENT_ID}  # 제공된 Client ID
            client-secret: ${SPOTIFY_CLIENT_SECRET}  # Client Secret 추가
            scope: user-read-email, user-read-private
            redirect-uri: "{baseUrl}/login/oauth2/code/{registrationId}"
            authorization-grant-type: authorization_code
            client-authentication-method: basic
            provider: spotify
        provider:
          google:
            authorization-uri: https://accounts.google.com/o/oauth2/auth
            token-uri: https://oauth2.googleapis.com/token
            user-info-uri: https://www.googleapis.com/oauth2/v3/userinfo
            user-name-attribute: sub
          jwt:
            issuer-uri: https://accounts.google.com
          spotify:
            authorization-uri: https://accounts.spotify.com/authorize
            token-uri: https://accounts.spotify.com/api/token
            user-info-uri: https://api.spotify.com/v1/me
            user-name-attribute: display_name

yml이 점점 길어져서 두렵다..

여튼 이럼 대애애애충 준비는 끝났다.

그럼 이제 얘도 시큐리티를 사용해서 처리를 하면 되는데 기존에 있던 로직을 사용하면 편할 것 같은데...

그러니까 CustomOAuth2UserService클래스에 spotify 관련해서 로직을 짜 넣은거.

그래서 기존 구글 로그인 로직을 조금 더 명확하게 메서드 이름을 바꿔주고.

processGoogleUser, createGoogleUserInLocalDB, processSpotifyUser, createSpotifyUserInLocalDB 이렇게 구현했다.

백엔드는 일단 원래 구글 로그인의 흐름을 따라가며 만들었기 때문에, 이제 index.jslogin.jsp 그리고 시큐리티만 손을 봐주면 될 것 같다.

index.js에는

// Spotify 로그인 함수 (Spring Security OAuth2 엔드포인트로 리다이렉트)
function spotifyLogin() {
    console.log('%c[INFO] Spotify 로그인 시도 중...', 'color: blue');
    // Spring Security의 OAuth2 로그인 엔드포인트로 리다이렉트
    window.location.href = "/oauth2/authorization/spotify";
}

// spotifyLogin 함수를 전역 스코프에 노출시킴
window.spotifyLogin = spotifyLogin;

이렇게!

"/oauth2/authorization/spotify"이 경로는 OAuth2 로그인 흐름을 시작하는 Spring Security의 엔드포인트이다.

여기서 OAuth2인증이 완료되면 xml에서 설정한 "{baseUrl}/login/oauth2/code/{registrationId}"이 경로로 리다이렉트 되서 나머지 로직을 처리하는것.

그럼 어차피 같은 OAuth2 인증이니 시큐리티는 수정없이 바로 로그인 테스트를 해보자.

여기서 스포티파이 로그인을 클릭해보면.

기존에 내가 사용중이던 계정이 바로 뜬다. 아마 로그인한 적 없는 사람이면 로그인 부터 하라고 뜰 듯.

여기서 동의를 눌러보자.

로그인 페이지로 리다이렉트 되어서 다시 로그인 시도 해봤는데 별다른 변화가 없다.

실패한듯 백엔드 콘솔로그를 찬찬히 보니까..

한번에 될리가 없지 ㅋㅋㅋㅋ

java.lang.IllegalArgumentException: This class supports client_secret_basic, client_secret_post, and none by default. Client [spotify] is using [basic] instead.
이게 지금 핵심 로고 같은데.

Spotify OAuth2 클라이언트가 기본적으로 client_secret_basic 방식으로 인증을 처리해야 하지만, 현재 설정이 basic으로 되어 있어서 발생하는 문제라고 한다.

client-authentication-method: client_secret_basic

이부분이 그냥 basic이였는데 client_secret_basic으로 고쳐주었다.

다시 시도.

일단 백엔드 접근까지는 성공했다.

이런 에러가 떴는데 아마 내가 구글 로그인 테스트할 때 썼던 이메일중 하나랑 겹쳐서 이런 에러가 뜬 것 같다.

그럼 뭐다? DB 초기화 하고 시도해보자.

우선 구글 로그인이 잘 작동되는지 확인했다. 구글로그인 문제없이 성공 DB에도 잘 들어왔다. 그럼 이제 스포티파이 회원이 2번 회원으로 잘 들어오면 된다.

ㄱㄱㄱㄱㄱㄱㄱ

ㅎㅎㅎㅎ 성공이당

메인 페이지 화면이다.

여기서 구글인지 스포티파이인지 구분하는 방법을 쓰는게 좋을 듯 하다. 그리고 스포티파이에서는 사용자 이름을 가져올 수는 없는가보다. DB 확인하니까 null로 들어있어서 사용자 이름이 뜨지 않네. 이건 나중에 회원 상세보기 기능에서 수정 기능을 제공하면 되니까 신경쓰지 말자. 내 DB에서는 이메일만 유일한 값이면 된다.

로그인 페이지 접근시도할 때 바로 메인으로 리다이렉트 되는 것도 보면 세션 유지도 잘 된다.

스포티파이로 소셜 로그인도 성공!

아 하는 김에 메인 페이지에 구글 스포티파이 구분 로직 만들고 포스팅 끝내야겠다.


띄웠다!

    @RequestMapping("/usr/home/main")
    public String showMain(@AuthenticationPrincipal OAuth2User oAuth2User, Model model) {
        System.err.println("===================메인페이지 접근=====================");
        if (oAuth2User != null) {
            String userName = oAuth2User.getAttribute("name");
            String userEmail = oAuth2User.getAttribute("email");

            // OAuth2 로그인 제공자 구분
            String provider = "";  // 로그인 제공자 구분 로직 추가
            if (oAuth2User.getAttributes().containsKey("sub")) { // 구글 로그인일 경우 "sub" 속성 존재
                provider = "google";
            } else if (oAuth2User.getAttributes().containsKey("id")) { // 스포티파이 로그인일 경우 "id" 속성 존재
                provider = "spotify";
            }

            model.addAttribute("provider", provider);  // 구글 or 스포티파이 제공자 정보
            model.addAttribute("userName", userName);  // 로그인한 사용자 이름
            model.addAttribute("userEmail", userEmail); // 로그인한 사용자 이메일


            // 세션 유지 확인 로그
            System.err.println("로그인된 사용자 이메일: " + userEmail);
            System.err.println("로그인된 사용자 이름: " + userName);
            System.err.println("OAuth2 로그인 제공자: " + provider);

        } else {
            model.addAttribute("userName", "Guest");
            System.err.println("로그인되지 않은 사용자: Guest");
        }

        return "usr/home/main"; // 메인 페이지 뷰
    }

이런 코드로 전달했고,

<!-- 로그인 제공자가 구글인지 스포티파이인지 확인 -->
<c:choose>
    <c:when test="${provider == 'google'}">
        <p>Google 사용자입니다.</p>
    </c:when>
    <c:when test="${provider == 'spotify'}">
        <p>Spotify 사용자입니다.</p>
    </c:when>
    <c:otherwise>
        <p>알 수 없는 로그인 제공자입니다.</p>
    </c:otherwise>
</c:choose>

JSP에서는 이렇게 받았다.

구글로 로그인 하면

이렇게 뜬다.

휴,,

구글 로그인 진짜 며칠동안 피똥싸가면서 만드니까 이건 빨리 되는구나 새삼 느낀다.

뿌듯하다!!!