check authenticated user in client components #1181
-
Hi, Well done with this library! Ho do I check If a user is authenticated in a client component? I believe next/headers only works in server components. |
Beta Was this translation helpful? Give feedback.
Replies: 5 comments 24 replies
-
Pass the current session/user as a prop, and possibly maybe use a context within said client component? |
Beta Was this translation helpful? Give feedback.
-
"use client";
import { User } from "lucia";
import { useEffect, useState } from "react";
import { validateRequest } from "@/features/auth/queries/validate-request";
const Header = () => {
// const { user } = await validateRequest(); // <--- server component approach
// client component approach v
const [user, setUser] = useState<User | null>(null);
useEffect(() => {
const fetchUser = async () => {
const { user } = await validateRequest();
setUser(user);
};
fetchUser();
}, []);
...
}; Whereas But you will get the typically SPA flicker. |
Beta Was this translation helpful? Give feedback.
-
|
Beta Was this translation helpful? Give feedback.
-
What about this? this implementation is doesn't convert the page to server-rendered on demand Header.txs "use client";
import React, { useEffect } from "react";
import { logout } from "@/serverActions/AuthenticAtion";
import useUserDataStore from "@/store.ts/UserState";
export default function Header() {
const { fetchUser, userData } = useUserDataStore();
useEffect(() => {
fetchUser();
}, [fetchUser]);
return (<>
...
{!userData ? (
<>
<li>
<Link href="/auth/signup">
<Button variant={"outline"}>Sign Up</Button>
</Link>
</li>
<li>
<Link href="/auth/signin">
<Button>Sign In</Button>
</Link>
</li>
</>
) : (
<>
<li>
{userData?.username}
</li>
<li>
<Link href="/auth/signin">
<Button onClick={async () => {
await logout();
fetchUser();
}}>Sign Out</Button>
</Link>
</li>
</>
)
...
<>) UserState.ts import { User } from "lucia";
import { create } from "zustand";
import { validateRequest } from "@/lib/auth/validateRequest";
interface UserState {
userData: User | null;
fetchUser: () => Promise<void>;
}
const useUserDataStore = create<UserState>((set) => ({
userData: null,
isLoading: false,
error: null,
fetchUser: async () => {
const { user } = await validateRequest();
set(() => ({ userData: user }));
},
}));
export default useUserDataStore; But this is exposing these... is there any thin way to prevent this exposer ? |
Beta Was this translation helpful? Give feedback.
-
After the user authenticates, save the non-sensitive information (e.g., userId) in the browser's/client's storage. Some options are:
|
Beta Was this translation helpful? Give feedback.
Well you can create an
/api/user
endpoint that returns the current user, but you'll have to implement it by yourself