코딩하는라민

[Supabase] 사용자의 계정 소유 확인 및 로그인 성공 여부 파악은 어떻게 이루어지는가? 본문

Serverless/Supabase

[Supabase] 사용자의 계정 소유 확인 및 로그인 성공 여부 파악은 어떻게 이루어지는가?

코딩하는라민 2024. 9. 18. 19:23
728x90
반응형

[Supabase] 사용자의 계정 소유 확인 및 로그인 성공 여부 파악은 어떻게 이루어지는가?

 

개인 프로젝트에서 Supabase 를 이용해 로그인/회원가입 기능을 구현했었다.

 

이와 관련된 질문을 받았을 때

"Supabase 에서는 로그인 시 사용자가 해당 계정의 주인임을 어떻게 확인하며, 로그인이 성공했음을 어떻게 확인하는 가"

라는 질문을 받았다.

 

당시에는 이 부분에 대해 잘 모르겠다고 대답했지만, 다시 생각해보니 내가 전혀 모르는 부분이 아니었다. 🥲

그때 당시 소유 확인은 모른다고 대답했고 로그인 성공 시에 Supabase 에서 반환하는 값들에서 uuid 를 통해 사용자를 구분하여 사용한다고 대답했었다. 질문자의 의도를 파악하지 못한 대답이었던 것이다.

 

그래서 본 포스팅에서는 Supabase의 Authentication 및 Authorization 의 과정에 대해 정리하고자 한다.

 

 

authentication & authorization 에 대해

`authentication` 는 인증으로 사용자가 제공한 email, password 등에 대해 사용자 본인이 맞는지 확인하는 과정이다.

` authorization` 는 권한 확인으로 사용자가 접근할 수 있는 리소스를 확인하는 것을 의미한다.

 

 

Supabase 의 로그인 로직

👨🏻‍💻 사용자가 해당 계정의 주인임을 어떻게 확인하나요?

🗣️ Supabase 는 사용자가 로그인할 때 제공한 이메일, 비밀번호를 서버에서 확인합니다.

서버는 사용자가 입력한 비밀번호와 데이터베이스에 저장된 해시화된 값과 비교하여 인증을 수행합니다. 비밀번호가 올바르면 해당 계정에 대한 고유 식별자인 `UUID`, `JWT` 를 반환합니다.

 

 

  • 사용자 입력 : 사용자가 이메일, 비밀번호를 입력하면 Supabase 는 이를 받아 인증을 시작합니다. 이때 입력된 정보는 데이터베이스에 저장된 사용자 계정 정보와 비교됩니다.
  • 인증 성공 여부 판단 : 사용자가 입력한 정보가 일치하는지 확인합니다.
  • 고유 식별자 반환 : 인증에 성공하면, Supabase 는 해당 사용자의 고유 식별자인 UUID 또는 JWT 를 반환합니다. JWT 는 이후 요청에서 사용자를 식별하는 중요한 역할을 하게 됩니다.
  • JWT 저장 : 클라이언트 측에서는 반환된 JWT 를 LocalStorage 또는 Cookies 에 저장하여 이후 요청에서 사용합니다.
  • 서버 요청 시 JWT 포함 : 사용자가 로그인된 상태로 애플리케이션에서 작업할 때, JWT 는 각 서버 요청에 포함되어 사용자가 권한이 있는지 확인하는 데 사용됩니다.

 

 

👨🏻‍💻 로그인이 성공적으로 이루어졌는지 어떻게 확인하나요?

🗣️  서버로부터 부여받은 `JWT(JSON Web Token)`을 통해 로그인이 성공적으로 이루어졌는지 확인할 수 있습니다.

Supabase 는 로그인 성공 시 JWT 를 발급하며, 이 토큰은 사용자의 인증 상태를 유지하는 데 사용됩니다. 클라이언트 측에서는 이 토큰을 `localStorage` 나 `cookies` 에 저장하고, 이후 API 요청 시 `Authorization 헤더` 에 이 토큰을 첨부하여 사용자의 권한을 확인하게 됩니다.

 

 

  • JWT 확인 : 클라이언트 측에서 서버로 요청을 보낼 때, 저장된 JWT가 요청의 Authorization 헤더에 포함됩니다. 이 토큰을 통해 서버는 요청이 인증된 사용자로부터 왔는지 확인합니다.
  • 서버에서 JWT 검증 : 서버는 JWT의 서명을 확인하고, 토큰이 만료되지 않았는지 확인합니다. 또한, 토큰이 변조되지 않았는지 확인합니다.
  • 권한 부여 : 서버는 RLS (Row-Level Security) 정책에 따라 토큰 내에 포함된 사용자 정보와 요청된 리소스의 권한을 비교합니다. 예를 들어, 사용자의 고유 ID와 요청된 데이터의 소유자 ID가 일치하는지 확인하여 권한이 있는지 결정합니다.
  • 권한에 따른 응답 : 만약 사용자가 요청한 데이터에 접근할 권한이 있다면, 서버는 데이터를 반환합니다. 그렇지 않을 경우, 서버는 접근을 제한하며 적절한 오류 메시지를 반환합니다.

 

 

로그인 성공 시 반환되는 값

다음 코드는 Supabase 에서 로그인 시 반환되는 값이다.

JWT 는 Base64 로 인코딩된 문자열로 되어 있으며, access_token 필드에서 가져올 수 있다.


{
  "access_token": "eyJhbGciOiAiSFMyNTYiLCAidHlwIjogIkpXVCJ9.eyJzdWIiOiAidXNlcmluZiIsICJuYW1lIjogIkpvaG4gRG9lIiwgImlhdCI6IDE2MTYzMjQ2OTksICJleHBzIjogMTYxNjMyODI5OX0.r5V8Tc62myd5f3dWmnN_zf8Ni22sD-Vz67zqBl2Xe4c",
  "expires_in": 3600,
  "refresh_token": "eyJhbGciOiAiSFMyNTYiLCAidHlwIjogIkpXVCJ9.eyJzdWIiOiAidXNlcmluZiIsICJpYXQiOiAxNjE2MzI0Njk5LCAiZXhwIjogMTYyMDI2ODI5OX0.0X7B4zwS6O_5YZZdSTHUs_B7JQbld9F0Bbr0i96LX7M",
  "token_type": "bearer",
  "user": {
    ...
  },
}
  • access_token : JWT 형식의 access token. 사용자가 인증되었음을 나타내며 API 요청 시 사용된다.
  • refresh_token : JWT 형식의 refresh token. access token 이 만료된 후 새로운 access token 을 발급받기 위해 사용된다.
  • token_type : 토큰의 타입으로 일반적으로 bearer 가 사용된다.
  • expires_in : access token 의 유효기간을 초단위로 나타낸다.

 

 

JWT 를 모든 요청마다 포함시켜야하나?

JWT를 모든 요청에 매번 포함시킬 필요는 없다.

`Supabase SDK` 는 사용자가 로그인을 하면 세션을 자동으로 유지하고, 인증 토큰을 모든 요청에 자동으로 포함시킨다. 따라서 클라이언트 측에서 매 요청마다 JWT 토큰을 명시적으로 포함시킬 필요가 없다.

* Supabase SDK 는 Supabase 의 다양한 서비스와 기능을 클라이언트 애플리케이션에서 쉽게 사용할 수 있도록 도와주는 소프트웨어 개발 키트이다. 쉽게 말해서 SDK 란 필요한 도구, 라이브러리, 문서 등을 모아놓은 패키지를 말하는 것이다.

 

SDK 는 RLS 정책 설정 유무와 관계없이 인증 토큰을 자동으로 처리한다.

즉, 요청에는 항상 인증 토큰이 포함되지만, 데이터 접근 제어는 RLS 정책을 설정해야만 제대로 이루어진다.

 

 

다음은 Supabase 에서 RLS 정책을 통해 사용자의 데이터를 조회하는 코드 예시이다. SDK 는 JWT 를 자동으로 모든 요청에 포함시키기 때문에 아래와 같이 클라이언트 측에서 JWT 를 명시적으로 포함시킬 필요가 없다.

// 선택한 날짜(year, month, date)에 해당하는 캘린더 데이터 조회
const { data, error } = await supabase
  .from('calendar')
  .select('*')
  .eq('created_at_year', selectedDate?.getFullYear())
  .eq('created_at_month', selectedDate?.getMonth() + 1)
  .eq('created_at_day', selectedDate?.getDate())

 

728x90
반응형