팀프로젝트

devnote 프로젝트 - 2

jjangsh 2024. 8. 30. 20:07

 

1. supabase로 회원가입

 

프로젝트 기획 후 초반에 초기 세팅을 해두었고 .env 파일도 생성해 두었기 때문에 Supabase 클라이언트 설정을 아래와 같이 바로 하였다.

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

const supabaseUrl = import.meta.env.VITE_SUPABASE_URL;
const supabaseKey = import.meta.env.VITE_SUPABASE_KEY;
const supabase = createClient(supabaseUrl, supabaseKey);

export default supabase;

 

 

 

나는 회원가입을 먼저 구현하기로 하고 만들어둔 pages/SignUp에서 작업을 진행했다.

 

const [formData, setFormData] = useState({
    name: '',
    nickname: '',
    email: '',
    password: '',
    confirmPassword: ''
  });

 

위처럼 사용자에게 여러 정보를 입력 받아 formData에 저장하였고, 이를 토대로 회원가입을 진행하였다.

 

아래 사진과 같이 supabase에서 DEV_USER이라는 테이블을 생성하고, id는 기본키로 유니크한 값이 들어가게 하고,

email과 name은 사용자에게 입력받은 값이 저장되게 하였다.

 

 

그리고 아래와 같이 회원이 입력한 정보가 테이블에 insert 되게 하였다.

const { data, error } = await supabase
  .from('DEV_USER')
  .insert({
    name: formData.name,
    email: formData.email
    password: formData.password
  })

if (error) {
  console.error( error )
} else {
  console.log( data )
}

 

 

이건 실제로 저장 된 모습!!

 

 

📌 하지만 문제가 있었다.

 

테이블에 password를 같이 저장해 버려서 뭔가 이상한 느낌이 들었다.

 

const hashedPassword = await bcrypt.hash(formData.password, 10);

      const { data, error } = await supabase.from('DEV_USER').insert({
        name: formData.name,
        email: formData.email,
        password: hashedPassword
      });

 

그래서 위처럼 bcryptjs 라이브러리를 사용하여 password를 암호화해서 저장시켰다.

 

 

위 사진처럼 실제로 암호화가 잘 되어서 저장이 됐다.

 

 

🔔나중에서야 알았지만 supabase는 기본적으로 제공되는 메서드들이 있고, 회원가입을 시켜주는 메서드를 사용하면 내가 따로 테이블을 만들지 않아도, 기본 제공되는 Users라는 테이블에 정보가 저장된다는 것!!

 

이를 토대로 supabase에서 제공되는 메서드로 회원가입을 해보았다. 아래는 그 코드이다.

const { error } = await supabase.auth.signUp({
          email: formData.email,
          password: formData.password,
          options: {
            data: {
              name: formData.name,
              nickname: formData.nickname
            }
          }
        });
 

supabase.auth.signUp이라는 메서드를 사용해서 nickname까지 추가로 받은 유저의 정보를 회원가입 시켜보았다.

 

 

 

위 사진은 실제로 회원가입을 진행 한 사용자들의 정보가 저장됐고, password라는 column이 존재하지 않았다.

 

그럼 password는 어디에 있을까?라고 생각을 하던 와중에 테이블 옆에 View user info라는 탭이 있어서 클릭해 보았다.

 

사진의 6번째 줄을 보면 supabase가 알아서 password를 암호화하여 잘 저장해 둔 것을 볼 수 있었다.

 

이렇게 회원가입 구현을 마치고 로그인 기능을 구현했다.

 

 

2. supabase로 로그인

 

로그인은 만들어준 pages/SignIn에서 작업하였다.

 

회원가입과 마찬가지로 formData state를 생성하고 사용자에게 받은 정보를 관리하였다.

const [formData, setFormData] = useState({ email: '', password: '' });

 

로그인도 supabase에서 기본 제공하는 메서드인 supabase.auth.signInWithPassword를 사용하였다.

아래는 코드이다.

const { error } = await supabase.auth.signInWithPassword({
          email: formData.email,
          password: formData.password
        });

 

이러면 로그인도 구현되었다.

 

3. supabase로 로그아웃

로그아웃도 supabase에서 제공하는 supabase.auth.signOut를 사용하면 간단하게 구현할 수 있었다.

const HandleSignOut = async () => {
    const { error } = await supabase.auth.signOut();
    if (error) {
      console.error('로그아웃 중 오류 발생:', error);
    } else {
      alert('로그아웃 처리가 완료 되었습니다. 메인 페이지로 이동합니다.');
    }
  };

 

이렇게 회원관리는 끝!!

 

...이면 좋겠지만 우리 팀은 UserContext를 생성하고 그 안에서 로그인한 유저의 상태를 전역으로 관리하기로 하였다.

 

 

4. UserContext

 

먼저 createContext()를 사용하여 UserContext를 생성하였다.

export const UserContext = createContext();

 

앞에 export를 붙여야 다른 곳에서 inport 해서 사용가능!

 

 

그리고 UserContextProvider를 만들고 그 안에 user state를 생성해서 로그인되어있는 유저의 상태를 관리한다.

export const UserContextProvider = ({ children }) => {
  const [user, setUser] = useState(null);
  };

 

그리고선 user를 가져오거나 상태를 변경해야 한다.

 

xport const UserContextProvider = ({ children }) => {
  const [user, setUser] = useState(null);

  useEffect(() => {
    const getSession = async () => {
      const response = await supabase.auth.getSession();
      const {
        id,
        email,
        user_metadata: { name, nickname }
      } = response.data.session.user;
      setUser({ id, email, name, nickname });
    };

    getSession();
  }, []);

 

위 로직은 페이지가 마운트 될 때 supabase에서 제공하는 메서드인 supabase.auth.getSession을 사용하여 user의 정보를 받아 온다. 그리고 받아온 정보를 response로 받았다.

 

response.user를 console을 찍어봤다.

 

원하는 정보만 user에 담기 위해 아래와 같이 정리를 해주고 setUser 해주었다.

const { id, email, user_metadata: { name, nickname } } = response.data.session.user;

 setUser({ id, email, name, nickname });

 

 

그리고 user를 console에 찍어보았다.

 

깔끔하게 원하는 정보들만 user에 담긴 모습을 볼 수 있다.

 

 

다음 글에서는 로그인 한 사용자의 정보를 담는 user를 이용하여 Router, ProtectRoute를 설정해 보겠다.