본문 바로가기
React & TypeScript

[TIL] supabase로 로그인과 회원가입 연동하기

by 어느새벽 2024. 6. 19.

supabase 링크 https://supabase.com/

 

Supabase | The Open Source Firebase Alternative

Build production-grade applications with a Postgres database, Authentication, instant APIs, Realtime, Functions, Storage and Vector embeddings. Start for free.

supabase.com

supabase 공식문서 링크 https://supabase.com/docs

 

Supabase Docs

 

supabase.com

 

 

 

1. supabase 에서 New project 만들기

 

 

비밀번호는 Generate a password로 자동생성한 후 Copy해서 따로 메모 저장해두기! 

 

2. supabase 공식 문서에서 Java Script 탭 눌러 작업하던 리액트 앱에 supabase 설치하기

// npm 설치

npm install @supabase/supabase-js

// yarn 설치

yarn add @supabase/supabase-js

 

3. 리액트 앱에 src 폴더에서 supabase 폴더를 만든 뒤 supabaseClient.js 파일 만들기

 

4. 다시 supabase에서 Project Settings > API 들어가서 Project URL과 anon 키 가져온 후

 

 

5. supabaseClient.js에 아래 처럼 코드 작성 (supabase 공식문서 > Java Script > Initialzing)

import { createClient } from "@supabase/supabase-js";

const supabase = createClient('프로젝트 URL', 'anon key')

export default supabase;

 

6. 리액트 앱에서 작업하던 회원가입 페이지에 코드 작성하기 ( supabase 공식문서 > Java Script > Create a new user)

const { data, error } = await supabase.auth.signUp({
  email: 'example@email.com',
  password: 'example-password',
})

 

// SignUp.jsx

import { useNavigate } from "react-router-dom";
import styled from "styled-components"
import supabase from "../supabase/supabaseClient";
import { useRef } from "react";

// styled-components 생략

function SignUp() {
  const navigate = useNavigate();
  const emailRef = useRef(null);
  const passwordRef = useRef(null);
  const nicknameRef = useRef(null);

  const goToLogin = () => {
    navigate('/Login');
  }

  const handleSignUp = async (e) => {
    e.preventDefault();
    const {data, error} = await supabase.auth.signUp({
      email : emailRef.current.value,
      password : passwordRef.current.value,
      nickname : nicknameRef.current.value,
    });

    if(error) {
      throw error;
    }

    console.log(data);
  }

  return (
    <>
      <StContainer>
        <StIdPwForm onSubmit={handleSignUp}>
          <StLoginTitle>회원가입</StLoginTitle>
          <StIdInput placeholder="@email.com" ref={emailRef}/>
          <StPwInput type="password" placeholder="비밀번호를 입력하세요." ref={passwordRef}/>
          <StNicknameInput placeholder="닉네임을 입력하세요." ref={nicknameRef}/>
          <StBtnBox>
            <StSignUpBtn
            >가입하기</StSignUpBtn>
            <StBackBtn
            onClick={goToLogin}>뒤로가기</StBackBtn>
          </StBtnBox>
        </StIdPwForm>
      </StContainer>
    </>
  )
}

export default SignUp

 

*form 태그 사용 시 submit 되면 새로고침 되기 때문에 함수에 e.preventDefault(); 넣어주기

 

브라우저 콘솔에서 data 확인 가능

 

supabase > Authentication 에서 회원가입 데이터 확인 가능

 

7. Last Sign in 에서 Waiting for verification.... 뜰 때 해결방법

 

Authentication > Providers > Email 에서 Confirm email 체크 해제 후 Save (다시 회원가입한 계정부터 적용됨)

 

8. 리액트 앱에서 작업하던 로그인 페이지에 코드 작성하기 ( supabase 공식문서 > Java Script > Sign in a user)

 

const { data, error } = await supabase.auth.signInWithPassword({
  email: 'example@email.com',
  password: 'example-password',
})

 

//Login.jsx

import { useRef } from "react";
import { useNavigate } from "react-router-dom";
import styled from "styled-components"
import supabase from "../supabase/supabaseClient";

// styled-components 생략

function Login() {
  const navigate = useNavigate();
  const idRef = useRef(null);
  const passwordRef = useRef(null);

  const goToSignUp = () => {
    navigate('/SignUp');
  }

  const handleLogin = async (e) => {
    e.preventDefault();
    const { data, error } = await supabase.auth.signInWithPassword({
      email: idRef.current.value,
      password: passwordRef.current.value,
    })
    if(error) {
      throw error;
    }
    console.log(data)
  }

  return (
    <>
      <StContainer>
        <StIdPwForm onSubmit={handleLogin}>
          <StLoginTitle>로그인</StLoginTitle>
          <StIdInput placeholder="아이디를 입력하세요." ref={idRef}/>
          <StPwInput placeholder="비밀번호를 입력하세요." ref={passwordRef}/>
          <StBtnBox>
            <StLoginBtn>로그인</StLoginBtn>
            <StSignUpBtn 
            onClick={goToSignUp}>회원가입</StSignUpBtn>
          </StBtnBox>
        </StIdPwForm>
      </StContainer>
    </>
  )
}

export default Login

 

브라우저 콘솔에서 data 확인 가능

9. supabase 회원정보의 보안을 위한 권한 설정하기

 

바로 위 이미지에서 Auth policy 클릭해서 

 

Create policy 클릭하기

 

우측에 여러가지 권한 설정을 정할 수 있는데 우선 INSERT를 선택하고 좌측에

(select auth.uid()) = user_id

자동으로 이렇게 나와 있을텐데 이 상태에서 Save policy를 누르면 바로 위에 알림으로 Error가 뜬다.

내가 이전에 콘솔에 찍어 확인한 데이터를 보면 user_id가 아닌 id 이기 때문이다.

  (select auth.uid()) = id

 위에 처럼 수정하여  Save policy를 누르면 된다. 

 

 

10. supabase에서 Table Editor에 사용할 table 만들기 

 

New table 클릭

table 이름 원하는대로 정해주고

Columns에 회원가입 할때 받아올 데이터 종류 모두 기입

id와 created_at은 자동 생성되어 있음

속성도 같이 설정한 후 Save

 

11. 회원가입 페이지에서 코드 추가하기 ( supabase 공식문서 > Java Script > Insert data )

 

// SignUp.jsx

import { useNavigate } from "react-router-dom";
import styled from "styled-components"
import supabase from "../supabase/supabaseClient";
import { useRef } from "react";

// styled-components 생략

function SignUp() {
  const navigate = useNavigate();
  const emailRef = useRef(null);
  const passwordRef = useRef(null);
  const nicknameRef = useRef(null);

  const goToLogin = () => {
    navigate('/Login');
  }

  const handleSignUp = async (e) => {
    e.preventDefault();
    const {data, error} = await supabase.auth.signUp({
      email : emailRef.current.value,
      password : passwordRef.current.value,
      nickname : nicknameRef.current.value,
    });

    if(error) {
      throw error;
    }

    console.log(data);
    
    const { data: user } = await supabase.from("user_table").insert({
      id: data.user.id,
      created_at: data.user.created_at,
      email: data.user.email,
      nickname: nicknameRef.current.value,
    });
  };

  return (
    <>
      <StContainer>
        <StIdPwForm onSubmit={handleSignUp}>
          <StLoginTitle>회원가입</StLoginTitle>
          <StIdInput placeholder="@email.com" ref={emailRef}/>
          <StPwInput type="password" placeholder="비밀번호를 입력하세요." ref={passwordRef}/>
          <StNicknameInput placeholder="닉네임을 입력하세요." ref={nicknameRef}/>
          <StBtnBox>
            <StSignUpBtn
            >가입하기</StSignUpBtn>
            <StBackBtn
            onClick={goToLogin}>뒤로가기</StBackBtn>
          </StBtnBox>
        </StIdPwForm>
      </StContainer>
    </>
  )
}

export default SignUp

 

user_table에서 확인 가능

 

 


실시간 유효성 검사를 위해 useState 사용한 로직은 아래 블로그 참조하면 너무너무 좋다.

https://velog.io/@hejin8307/React-Typescript-%ED%9A%8C%EC%9B%90%EA%B0%80%EC%9E%85-%EA%B5%AC%ED%98%84-Feat-%EC%9C%A0%ED%9A%A8%EC%84%B1-%EA%B2%80%EC%82%AC

 

React + Typescript + Redux - 회원가입 구현 (Feat 유효성 검사, 리팩토링)

Typescript 환경에서 구현 중인 프로젝트에서 회원가입과 로그인을 맡게 되었고 먼저 회원가입부터 어떤 방법으로 구현했는지 공유해보고자 한다. 🛠 기능 > 1. 아이디, 비밀번호, 이메일, 휴대폰

velog.io