实用指南:【前端学习】仿Deepseek官网AI聊天网站React

登录

npm run dev启动项目

默认界面

Clerk | Authentication and User Management

援助开发者迅速集成用户相关功能,无需从零构建繁琐的认证与用户体系,从而聚焦核心业务开发。它不仅覆盖基础的登录 / 注册,还提供组织管理、账单集成、安全防护等一站式解决方案,广泛适用于 SaaS、移动应用、网页应用等各类产品。

创建应用

npm install @clerk/nextjs

Next.js项目中安装 Clerk 身份验证工具包

创建.env文件

NEXT_PUBLIC_CLERK_PUBLISHABLE_KEY=pk_test_cXVpY2stZ2FubmV0LTc3LmNsZXJrLmFjY291bnRzLmRldiQ
CLERK_SECRET_KEY=##

Clerk 身份验证服务的配置密钥,用于在应用中与 Clerk 服务进行安全通信

客户端公开密钥服务器端私有密钥必须严格保密,绝不能暴露在前端代码或公开仓库中)

更新middleware.ts

import { clerkMiddleware } from '@clerk/nextjs/server';

export default clerkMiddleware();

export const config = {
matcher: [
// Skip Next.js internals and all static files, unless found in search params
'/((?!_next|[^?]*\\.(?:html?|css|js(?!on)|jpe?g|webp|png|gif|svg|ttf|woff2?|ico|csv|docx?|xlsx?|zip|webmanifest)).*)',
// Always run for API routes
'/(api|trpc)(.*)',
],
};

将 ClerkProvider 添加到应用

ClerkProvider组件向应用提供 Clerk 的身份验证上下文,使用 ClerkProvider 在入口点包装整个应用,以使身份验证可全局访问

return (
<ClerkProvider>
<html lang="en">
<body
className={`${geistSans.variable} ${geistMono.variable} antialiased`}
>
{children}
</body>
</html>
</ClerkProvider>
);

Next.js 应用中使用 Clerk 身份验证服务时的根布局部署,首要作用是将 Clerk 的认证上下文注入整个应用,并设置基础页面结构

只有被ClerkProvider包裹的组件,才能使用 Clerk 的各种功能

lang="en"指定页面语言为英语

body页面主体容器,所有可见内容都会渲染在这里

${geistSans.variable} ${geistMono.variable} antialiased是一些样式类

{children}是 Next.js App Router 中的特殊语法,代表当前布局下所有页面的内容

例如,当用户访问 /about 页面时,children 就会渲染 about/page.tsx 中的内容

使用 Clerk 为 Next.js 应用构建自己的登录或登录页面

app/
└── sign-in/
└── [[...sign-in]]/
└── page.tsx

[[...sign-in]] 是 Next.js 的可选捕获所有路由匹配所有以 /sign-in 开头的路径,确保 Clerk 组件能正确处理各种登录流程中的跳转就是(optional catch-all route),作用

在 page.tsx 中写入以下代码:

import { SignIn } from '@clerk/nextjs'

export default function Page() {
return <SignIn />
}

在 Next.js 应用中创建一个完整的登录页面,使用 Clerk 提供的 <SignIn /> 组件快速完成登录功能,无需手动开发登录表单

import { SignIn } from '@clerk/nextjs':从 Clerk 的 Next.js SDK 中导入了预构建的 <SignIn /> 组件,这个组件含有了所有登录所需的功能。

export default function Page() {...}:Next.js 中定义页面的标准方式,该组件会在访问对应路由时渲染

return :直接渲染了 Clerk 的登录组件,该组件会自动生成一个功能完整的登录界面

import { SignIn } from '@clerk/nextjs'

export default function Page() {
return <div className='h-screen w-screen flex items-center justify-center'>
<SignIn />
</div>
}

外层的 div 使用了几个关键的 CSS 类:

  1. h-screen:让 div 的高度等于屏幕高度
  2. w-screen:让 div 的宽度等于屏幕宽度
  3. flex items-center justify-center:应用 Flex 布局,让内部的 <SignIn /> 组件在水平和垂直方向都居中显示

<SignIn /> 会生成 Clerk 的登录界面,结合外层 div 的样式,最终效果是:登录表单在整个屏幕的正中央显示

将登录或登录路线设为公共

在已用clerkMiddleware保护所有路由的前提下,单独将登录页面(/sign-in相关路径)设为“公开路由”,避免用户因未登录被无限重定向(比如没登录时访问登录页,却被保护机制拦截)

clerkMiddleware 有两种常见配置逻辑:

  1. 默认公开所有路由:只保护指定路由(需手动配备哪些路由要登录);
  2. 默认保护所有路由:所有路由都需要登录才能访问,仅手动指定的 “公共路由” 可无需登录。

属于第 2 种场景 ——先假设所有路由都需要保护,再单独把登录页(/sign-in)设为公共路由,确保用户能正常访问登录页来登录账号

import { clerkMiddleware, createRouteMatcher } from '@clerk/nextjs/server'

const isPublicRoute = createRouteMatcher(['/sign-in(.*)'])

export default clerkMiddleware(async (auth, req) => {
if (!isPublicRoute(req)) {
await auth.protect()
}
})

export const config = {
matcher: [
// Skip Next.js internals and all static files, unless found in search params
'/((?!_next|[^?]*\\.(?:html?|css|js(?!on)|jpe?g|webp|png|gif|svg|ttf|woff2?|ico|csv|docx?|xlsx?|zip|webmanifest)).*)',
// Always run for API routes
'/(api|trpc)(.*)',
],
}

const isPublicRoute = createRouteMatcher(['/sign-in(.*)']):定义公共路由:标记登录页为无需保护

  1. 当用户访问任意路由时,中间件会先接收请求(req);
  2. 用isPublicRoute(req)判断 “当前访问的是不是登录相关公共路由”;
    1. 如果是:!isPublicRoute(req) 为 false,不执行 auth.protect(),用户可直接访问;
    2. 如果不是(比如访问 /dashboard、/profile):!isPublicRoute(req) 为 true,执行 auth.protect();
  3. :就是auth.protect():Clerk 的 “路由保护函数”,作用
    1. 若用户已登录:允许访问该路由;
    2. 若用户未登录:自动重定向到登录页(/sign-in),让用户先登录。

更新环境变量

通过配置 环境变量来控制 Clerk 登录组件(<SignIn />)的跳转逻辑,确保用户在登录、注册流程中能被正确引导到目标页面,避免跳转混乱

NEXT_PUBLIC_CLERK_SIGN_IN_URL=/sign-in

用于调整 Clerk 登录页面地址的前端环境变量,核心作用是告诉 Clerk 前端组件:你的应用中登录页面的具体路由地址是 /sign-in

登录界面

注册登录后进入首页:

posted @ 2025-11-11 19:39  gccbuaa  阅读(17)  评论(0)    收藏  举报