会话管理与 useSession 钩子
在服务器端和客户端组件中访问会话数据,并根据身份验证状态保护页面。
会话管理与 useSession 钩子 是 CoddyKit 上的免费 React Academy 课时。 这是第 2 节课,共 4 节。 你可以在下方免费阅读本课时的完整内容 — 然后在浏览器中使用内置代码编辑器和全天候 AI 导师进行实践。 这是 React Academy 学习路径的一部分,你的进度在网页和 CoddyKit 应用中同步。 React Academy 课程共包含 4 节课。
Auth.js 中的会话类型
Auth.js 支持两种会话策略:JWT(默认,将无状态令牌存储在 Cookie 中)和数据库(将会话记录存储在数据库中,可以在服务器端使其失效)。
客户端组件中的 useSession
useSession() 是一个用于读取当前会话的客户端组件钩子。它会返回 data(会话)、status('loading' | 'authenticated' | 'unauthenticated')以及一个 update 函数。
'use client';
import { useSession } from 'next-auth/react';
export function UserAvatar() {
const { data: session, status } = useSession();
if (status === 'loading') return <Spinner />;
if (status === 'unauthenticated') return <Link href="/login">Sign in</Link>;
return <img src={session.user?.image ?? ''} alt={session.user?.name ?? ''} />;
}设置 SessionProvider
使用 SessionProvider 包装应用(或客户端组件子树),这样 useSession 就能访问会话上下文。
// app/providers.tsx
'use client';
import { SessionProvider } from 'next-auth/react';
export function Providers({ children }: { children: React.ReactNode }) {
return <SessionProvider>{children}</SessionProvider>;
}
// app/layout.tsx
import { Providers } from './providers';
export default function RootLayout({ children }) {
return <html><body><Providers>{children}</Providers></body></html>;
}服务器组件中的 auth()
对于服务器组件,请直接使用 auth(),不需要钩子,也不需要提供商。它会从服务器端 Cookie 中读取会话。
import { auth } from '@/auth';
export default async function Header() {
const session = await auth();
return (
<nav>
{session ? (
<span>Hello, {session.user?.name}</span>
) : (
<Link href="/login">Sign in</Link>
)}
</nav>
);
}保护客户端路由
将 useSession 与 required: true 选项结合使用,可以将未通过身份验证的用户自动重定向到登录页面。
'use client';
import { useSession } from 'next-auth/react';
export default function ProtectedPage() {
const { data: session } = useSession({ required: true });
// session is never null here — unauthenticated users are redirected
return <div>Welcome, {session?.user?.name}</div>;
}更新会话
调用 useSession 返回的 update() 函数,即可刷新会话,例如在更新个人资料后,无需退出再重新登录。
const { data: session, update } = useSession();
async function handleNameChange(newName: string) {
await updateUserName(newName); // API call
await update({ user: { name: newName } }); // refresh session
}JWT 会话回调
使用 jwt 回调在登录时向 JWT 令牌添加自定义数据,并使用 session 回调将这些数据公开到会话对象中。
callbacks: {
async jwt({ token, user }) {
if (user) token.role = user.role; // add on first sign-in
return token;
},
async session({ session, token }) {
session.user.role = token.role as string;
return session;
},
},会话过期
在 Auth.js 配置中设置会话的最长有效期。活动中的 JWT 会话会在每次请求时自动刷新。
export const { handlers, auth } = NextAuth({
session: {
strategy: 'jwt',
maxAge: 30 * 24 * 60 * 60, // 30 days
updateAge: 24 * 60 * 60, // refresh if older than 1 day
},
});使数据库会话失效
可以在服务器端撤销数据库会话,这对于强制退出登录很有用。删除数据库中的会话记录即可立即使该会话失效。
// Server Action to log out all devices:
async function logOutAllDevices() {
'use server';
const session = await auth();
if (session) await db.session.deleteMany({ where: { userId: session.user.id } });
redirect('/login');
}客户端组件中的基于角色的访问控制
从 useSession 中读取会话角色,并根据角色有条件地渲染界面。
const { data: session } = useSession();
const isAdmin = session?.user?.role === 'admin';
return (
<>
{isAdmin && <AdminPanel />}
<UserContent />
</>
);快速检查
要让客户端组件中的 useSession() 正常工作,必须使用哪个提供商包装应用?
回顾
在服务器组件中使用 auth() 访问会话,在由 SessionProvider 包装的客户端组件中使用 useSession()。通过 JWT 和会话回调添加自定义数据,使用 update() 在客户端更新会话,并配置 maxAge 控制会话过期时间。
常见问题解答
「会话管理与 useSession 钩子」课时是免费的吗?
是的 — 「会话管理与 useSession 钩子」的完整文本可在网页上免费阅读。要进行交互式练习(内置代码编辑器和全天候 AI 导师)并解锁 React Academy 课程的其余内容,请升级到 CoddyKit PRO。 React Academy 课程共包含 4 节课。
「会话管理与 useSession 钩子」这节课中我会学到什么?
在服务器端和客户端组件中访问会话数据,并根据身份验证状态保护页面。 你通过在浏览器中直接运行的动手代码来练习 React Academy,全天候 AI 导师会在你学习这节课的过程中回答你的问题。
学习 React Academy 需要有经验吗?
无需任何先前经验。CoddyKit 上的 React Academy 课程适合初学者到高级学习者,你可以从这里开始或从头开始,按照自己的节奏学习。 这是第 2 节课,共 4 节。
「会话管理与 useSession 钩子」课时需要多长时间?
大多数 CoddyKit 课程大约需要 5–10 分钟。每节课都很精短且互动,所以你能稳步进步,并在网页和应用中从离开的地方继续。
我能在这节 React Academy 课中编写并运行代码吗?
能。每节 React Academy 课都包含内置代码编辑器,你可以在浏览器中直接编写并运行真实代码,并获得即时 AI 反馈 — 无需本地设置。
此课程中的所有课时
- 在 Next.js App Router 中设置 Auth.js
- 会话管理与 useSession 钩子
- 凭据提供商与自定义登录
- 基于中间件的路由保护