🌱 ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • [WizSched] Supabase와 Google OAuth를 이용한 로그인 구현
    Front-End/Project 2024. 1. 26. 06:14
    🍀 목차
    Supabase 설정
    OAuth 기본
    Google Cloud Platform 설정
    로그인 구현

     

     

     

    Supabase 설정

     

     

    우선 supabse를 설치한다. 

    yarn add @supabase/supabase-js

     

    인증 시스템에는 두 부분이 있다.

    • Authentication(인증) : 특정 사용자의 신원을 확인한다. 이 사람을 허용해야 하는가? 그렇다면, 누구인가?
    • Authorization(인가) : 특정 사용자가 특정 자원에 접근하거나 사용할 수 있는 권한을 부여한다. 들어가면, 무엇을 할 수 있는가?

     사용자의 신원을 확인하여 인증하고 로그인하면, 인가를 통해 특정 자원에 대한 권한 부여 및 관리를 하게 된다. 

     

     

    Authentication

    인증 또한 여러 방법이 있다.

    • email, phone, password 같은 password-based 방법
    • magiclink(사용자가 전송받은 링크를 클릭하면 자동으로 인증되고 로그인되는 방식), OTP(일회용 비밀번호) 같은 passwordless 방법
    • OAuth 소셜 공급업체를 이용하는 방법
    • SAML SSO : Security Assertion Markup Language, 웹 기반 인증을 위한 XML기반 표준. SSO(단일 로그인) 시스템에서 사용된다. 서비스 제공자에게 SAML Assertions(사용자 신원 및 권한 정보를 담고 있음)을 전송하여 사용자를 인증한다. 

     

     프로젝트에서 사용할 방법은 OAuth 소셜 공급업체를 이용하는 방법이며, Supabase의 Auth 기능을 사용한다. 

    Supabase 대시보드에서 Google provider를 구성한다. 

     

    google provider 화면

     

     Google 로그인을 사용하려면 Google Cloud Platform 계정을 만들어야 한다. 

     

    OAuth 기본

    기본적인 OAuth에 대해 알아보자.

     OAuth(Open Authorization 또는 Open Authentication)는 개방형 표준 인증 프로토콜로서 웹사이트에 신규 가입하지 않고 자신의 소셜 미디어 플랫폼등의 계정으로 로그인할 수 있게 해주는 방식이다. 핵심은 인가(Authorization)토큰(Token)이다. 

    OAuth 2.0 흐름

     

    • Client : 앱이다. 리소스 소유자를 대신하여 보호된 리소스에 대해 리소스 서버에 요청을 보낸다. 리소스 소유자는 보호된 리소스에 액세스 할 수 있는 권한을 앱에 부여해야 한다.
    • Resource Owner(리소스 소유자) : 최종 사용자. 보호 대상 리소스에 대한 액세스 권한을 부여할 수 있다. 리소스 소유자만이 데이터에 대한 액세스 권한을 앱에 부여할 수 있다.
    • Resource Server(리소스 서버) : 서비스. 리소스 서버는 보호된 리소스를 앱에 제공하기 전에 일종의 승인을 요구한다. 
    • Authorization Server(승인 서버) : OAuth 2.0 사양을 준수하여 구현되며, 승인 부여 검증 및 리소스 서버에서 사용자 데이터에 액세스할 수 있는 권한을 부여하는 액세스 토큰 발급을 담당한다. 
    • Authorization grant(승인 부여) : 최종 사용자를 대신하여 액세스 토큰을 검색할 수 있는 권한을 앱에 부여한다.
      • 승인 코드 : 승인 서버가 액세스 토큰을 발급하려면 먼저 리소스 서버에서 승인 코드를 받아야 한다. 일반적으로 앱이 서버에 있는 경우 사용된다. 앱에서 리소스 서버의 로그인 페이지로 브라우저를 열고 실제 계정에 로그인하도록 요청한다. 로그인에 성공하면 앱은 승인 서버와 액세스 토큰을 협상하는 데 사용할 수 있는 승인 코드를 수신한다. 3-legged OAuth라고도 한다.
      • 암묵적 방법 : 승인 코드의 약식 버전. 일반적으로 앱이 클라이언트에 있을 때 사용된다. 앱의 코드가 별도의 웹 서버에서 상주하며 실행되는 대신 스크립팅 언어를 사용하여 브라우저에 구현된다. 별도의 승인 코드를 먼저 발급하지 않고 사용자가 인증되면 액세스 토큰을 직접 반환한다. 
      • 리소스 소유자의 암호 자격증명 : 승인 서버가 사용자 이름/비밀번호를 확인하면 클라이언트에 액세스 토큰이 발급된다. 신뢰도 높은 애플리케이션에서는 이 흐름을 사용하는 것이 좋다. 
      • 클라이언트 자격증명 : 클라이언트 앱이 자체적으로 작동하는 경우 고려한다. 클라이언트가 리소스 소유자다. 앱은 승인 서버에 클라이언트 ID와 클라이언트 보안 비밀번호 키를 제시하여 액세스 토큰을 받을 수 있다.  Firebase나 Supabase처럼 백엔드 데이터 스토리지 서비스에 액세스해야 할 때 사용된다. 
    • Access token(액세스 토큰) : 보호된 리소스에 액세스 하는 데 사용되는 사용자 인증 정보 역할을 하는 긴 문자열이다.
    • Protected resource(보호된 리소스) : 리소스 소유자가 소유한 데이터이다. 민감한 정보를 포함한다. 

     

    Google Cloud Platform 설정

     

     OAuth 클라이언트 Id, 비밀번호가 필요하다. Google Cloud Platform에서 프로젝트를 생성한다.

     

    프로젝트 생성
    새 프로젝트 생성

     

    이제 OAuth 동의 화면을 만들어야 한다. API 및 서비스의 OAuth 동의 화면을 들어간다. 

     

    API 및 서비스 > OAuth 동의 화면

     

    외부를 선택 후 만들어준다.

     

    동의 화면에서 외부를 클릭한 상태

     

    앱 이름, 사용자 지원 이메일, 개발자 연락처 정보는 필수값이다. 입력하고 저장 후 계속을 클릭한다.

    범위에서는 어떤 범위를 허용시킬지 추가한다. 내 프로젝트에서는 이메일 주소, 개인정보, 구글 캘린더 API의 특정 기능들을 사용하기에 관련 범위를 추가해 주었다. 

    추가된 범위들.

     

     만약 .../auth/calendar.을 추가한다면 이 범위는 .../auth/calendar.readonly, .../auth/calendar.events.readonly등의 상위 범위이기에 하위 범위들이 모두 추가되게 된다. 프로젝트에서 사용할 API들이 설명에 다 포함되어 있어 설정했지만, 민감한 범위를 추가할 때는 정말 필요한 API만이 포함되어 있는지 확인하는 것이 좋아 보였다. 또한, 민감한 범위를 추가하면 구글에서 애플리케이션에 대한 인증을 거쳐야한다. 

     

     

    테스트 사용자는 우선 추가 없이 넘어갔다. 

    요약 부분이 뜨면 확인 후 대시보드로 돌아간다.

     

     

    이제 Supabase를 위해 필요한 OAuth 클라이언트 ID, 비밀번호를 만들어야 한다.

     

     

    사용자 인증 정보 -> 사용자 인증정보 만들기 -> OAuth 클라이언트 ID

     

    사용자 인증 정보 -> 사용자 인증 정보 만들기 -> OAuth 클라이언트 ID를 클릭한다.

     

    필요 정보를 입력하는 사진

     

    프로젝트의 유형과 주소가 있다면 입력해 준다. 승인된 자바스크립트 원본에는 로컬 환경에서의 주소와 vercel 배포 주소를 입력해 주었다. 

    승인된 리다이렉션 URI에는 인증 후에 이동할(리다이렉션 될) URI를 입력해 준다. Supabase의 Callback URL을 추가해 준다.

     

    Google Provider Callback URL
    Google Provider Callback URL

     

     

    정보 입력이 완료되면 만들기로 OAuth 클라이언트를 생성해 준다.

     

    클라이언트 생성 완료

     

    이제 클라이언트 ID와 비밀번호를 얻게 되었다! 비밀번호의 경우는 절대 노출되면 안 되기에 공개된 장소에는 노출시키지 않는다. 

     


    로그인 구현

     

      Google Provider에 클라이언트 ID, 비밀번호를 입력하고 저장해 준다. 

     

    google 연결 완료 사진
    연결 완료!

     

    프로젝트 대시보드

     

    URL Configuration -> Redirect URLs에서 Add URL로 웹 사이트 주소를 넣어준다(인증 성공 후 Redirect될 URL들).

     

    const { data, error } = await supabase.auth.signInWithOAuth({
      provider: 'google',
      options: {
        queryParams: {
          access_type: 'offline',
          prompt: 'consent',
        },
      },
    })

     

    options에 아래 속성을 추가하면 oauth 요청 시에 query parameter로 access_type은 offline, prompt는 consent가 붙어 가게 된다. 

    offline은 리프레시 토큰을 얻을 수 있게 해 주며, consent는 사용자에게 동의를 구하는 prompt를 표시하도록 한다. 해당 코드는 supabase라는 클라이언트 객체를 만들어야 사용할 수 있다.

     

    레퍼런스를 참고하여 createClient를 만들어준다. 만드는 데 필요한 URL과 Key는 프로젝트 대시보드의 Setting -> API에서 확인할 수 있다.

     

    위치를 표시한 사진

     

    import { createClient } from '@supabase/supabase-js';
    
    const supabaseUrl = process.env.VITE_SUPABASE_URL as string;
    const supabaseKey = process.env.VITE_SUPABASE_KEY as string;
    
    const supabase = createClient(supabaseUrl, supabaseKey);
    export default supabase;

     

    vite에서는 환경 변수를 import.meta.env 객체를 통해 접근할 수 있지만 vercel에 배포된 프로젝트의 경우에는 이를 제대로 인식하지 못해 vite의 config파일을 수정해주어야 한다. vite 관련 문서를 보고 설정에 맞게 작성해 주었다.

     

    이제 클라이언트를 만들었으니 다시 로그인 코드를 이어주었다.

     

    로그인 커스텀 훅 불러오기

     

     

    로그인 버튼을 클릭한 후. 구글 페이지로 이동하였다.
    로그인 버튼을 클릭하니...

     

     

    엑세스 차단 사진
    403 에러가 떴다.

     

    해당 에러를 해결하려면 현재 아이디를 테스트 아이디로 추가하거나, 프로젝트 개시 상태를 프로덕션으로 하면 된다. 

     

    앱 게시 버튼의 위치
    앱을 게시하거나
    테스트 사용자를 추가한다.

     

     우선 테스트 사용자로 추가해 주었다. 다시 시도해 보면 화면이 바뀌어있다. 계속을 클릭하면 된다.

    경고 표시. 계속을 클릭한다.

     

    설정된 API에 접근을 허용시키면 Redirect 된다. 다시 대시보드로 가서 확인해 보면...

     

    대시보드의 Users. 로그인 된 사용자의 정보를 볼 수 있다.
    Users로 들어간다.

     

    해당 계정이 로그인되었다! 유저 정보는 supabase.auth.getUser()getSession()등으로 확인해 볼 수 있다.

     

    참고자료

    https://supabase.com/docs

    https://cloud.google.com/apigee/docs/api-platform/security/oauth/oauth-introduction?hl=ko

    https://vercel.com/docs/frameworks/vite#environment-variables

    https://vitejs.dev/config/#using-environment-variables-in-config

    https://developers.google.com/identity/protocols/oauth2/web-server

     

    댓글

🍀 Y0ungZ dev blog.
스크롤 버튼