Router
const Router = () => {
const { user } = useContext(UserContext);
const publicRoutes = [
{
path: '/',
element: <Home />
},
{
path: '/detailpost/:id',
element: <DetailPost />
}
];
// 로그인하지 않은(인증되지 않은) 사용자 전용 라우트
const routesForNotAuthenticatedOnly = [
{
path: '/signin',
element: <SignIn />
},
{
path: '/signup',
element: <SignUp />
}
];
const routesForAuthenticatedOnly = [
{
path: '/auth',
element: <ProtectedRoute />,
children: [
{
path: 'mypage',
element: <MyPage />
},
{
path: 'newpost',
element: <NewPost />
},
{
path: 'editpost/:id',
element: <EditPost />
}
]
}
];
const notFound = {
path: '*',
element: <Navigate to="/" />
};
// createBrowserRouter로 라우터 생성
// createBrowserRouter: 라우터를 정의하는 기본 함수, 여러 그룹의 라우트를 한 번에 관리할 수 있게 함
const router = createBrowserRouter([
{
path: '/',
element: <Layout />,
children: [
// 라우트 설정들
...publicRoutes,
...routesForAuthenticatedOnly, // user가 true일 때 Home이 보여짐 + Protected Routes를 구현함 (경로를 찾을 때 위에서부터 확인 따라서 먼저 보이는 인증된 사용자용 "/"로 이동하는 것)
...(!user ? routesForNotAuthenticatedOnly : []), // user가 false일 때 라우트에 포함되고, 아니라면 빈 배열
notFound
]
}
]);
return <RouterProvider router={router} />;
};
export default Router;
로그인하면 갈 수 있는 라우터와 아닌 라우터를 구분해 놓고 마지막에 로그인한 사용자의 정보를 담은 user의 유무로 최종 판단한다.
ProtectedRoute
export const ProtectedRoute = () => {
const { user } = useContext(UserContext);
const { pathname } = useLocation();
if (!user) {
return <Navigate to="/signin" replace state={{ redirectedFrom: pathname }} />;
}
return <Outlet />;
};
로그인 되어있지 않은 경우 sign-in으로 replace 옵션으로 redirection
replace, push가 있는데 뒤로 가기 가능 여부가 다름
redirect pathname을 기억할 수 있도록 state를 지정해 줌 (어디서 왔는지 저장 -> 로그인 후 거기로 돌아감)
마지막 Outlet은 보호된 라우트 내에서 자식 라우트를 렌더링한다.
회원 정보 테이블
로그인, 회원가입 기능을 다 구현하고 수정을 하려고 하는데, 프로필 이미지도 선택을 하게 하고 싶었다.
또 이름, 닉네임, 프로필 이미지 url 등 많은 정보를 auth.users 테이블에 모두 담는 것은 공식 문서에서도 추천하지 않는다고 되어 있었다.
그래서 auth.users의 기본 키(primary key)인 id를 참조하는 public.profile이라는 테이블을 생성하고 name, nickname, avatarUrl을 저장하는 column을 생성하였다.
하지만 테이블만 생성한다고 끝이 아니고 함수와 트리거를 만들어줘야 auth.users에 정보가 추가될 때, public.profile에도 추가가 된다.
create policy "public profiles are viewed by everyone." on profile
for select using(true);
create policy "Users can insert their own profile." on profile
for insert with check(auth.uid()=id);
create function public.handle_new_user()
returns trigger as $$
begin
insert into public.profile (id, email, name, nickname, avatar_url)
values (new.id, new.email, new.raw_user_meta_data->>'name', new.raw_user_meta_data->>'nickname', new.raw_user_meta_data->>'avatar_url');
return new;
end;
$$ language plpgsql security definer;
create trigger on_auth_user_created
after insert on auth.users
for each row execute procedure public.handle_new_user();
전체 코드
create policy "public profiles are viewed by everyone." on profile
for select using(true);
- 설명: 이 정책은 profile 테이블에 대한 조회 권한을 설정합니다.
- 의미: 누구나 profile 테이블의 내용을 조회할 수 있도록 허용합니다.
- 구체적인 작업: select 권한에 대해 using(true) 조건을 적용하여, 모든 사용자가 profile 테이블을 조회할 수 있도록 합니다.
create policy "Users can insert their own profile." on profile
for insert with check(auth.uid()=id);
- 설명: 이 정책은 사용자가 자신의 프로필을 삽입할 수 있도록 허용합니다.
- 의미: 사용자가 자신의 프로필만 삽입할 수 있도록 제한합니다.
- 구체적인 작업: insert 권한에 대해 auth.uid() = id 조건을 사용하여, 삽입되는 프로필의 id 값이 현재 인증된 사용자의 uid와 일치하는 경우에만 삽입이 허용됩니다.
create function public.handle_new_user()
returns trigger as $$
begin
insert into public.profile (id, email, name, nickname, avatar_url)
values (new.id, new.email, new.raw_user_meta_data->>'name', new.raw_user_meta_data->>'nickname', new.raw_user_meta_data->>'avatar_url');
return new;
end;
$$ language plpgsql security definer;
- 설명: handle_new_user라는 함수를 생성합니다.
- 의미: 새로운 사용자가 생성될 때 자동으로 profile 테이블에 해당 사용자의 정보를 삽입하기 위한 함수입니다.
- 구체적인 작업:
- 새 사용자가 auth.users 테이블에 추가되면, 이 함수는 profile 테이블에 새로운 프로필을 생성합니다.
- new.id, new.email, new.raw_user_meta_data->>'name', new.raw_user_meta_data->>'nickname', new.raw_user_meta_data->>'avatar_url' 값을 사용하여 프로필을 삽입합니다.
create trigger on_auth_user_created
after insert on auth.users
for each row execute procedure public.handle_new_user();
- 설명: on_auth_user_created라는 트리거를 생성합니다.
- 의미: auth.users 테이블에 새로운 행이 삽입될 때마다 handle_new_user 함수를 자동으로 호출하도록 설정합니다.
- 구체적인 작업: 새로운 사용자가 auth.users 테이블에 추가되면, 트리거가 실행되어 profile 테이블에 해당 사용자의 프로필이 생성됩니다.
회원 정보 수정 코드
supabase.from('어떤 테이블').update(뭐를).eq('id', user.id);
supabase에서 제공하는 메서드를 사용하면 간단하게 회원 정보를 수정할 수 있었다.
'팀프로젝트' 카테고리의 다른 글
food compass 프로젝트 - 최종 (7) | 2024.09.23 |
---|---|
food compass 프로젝트 트러블 슈팅 (0) | 2024.09.20 |
devnote 프로젝트 - 4 최종 (1) | 2024.09.04 |
devnote 프로젝트 - 2 (0) | 2024.08.30 |
devnote 프로젝트 - 1 (4) | 2024.08.29 |