从0死磕全栈之Next.js 应用中的认证与授权:从零实现安全用户系统

在现代 Web 开发中,认证(Authentication)授权(Authorization) 是构建安全应用的核心环节。Next.js 14 引入的 App Router 架构结合 React Server Components 与 Server Actions,为开发者提供了更安全、更高效的认证实现方式。

本文将带你从零搭建一个具备完整认证与授权能力的 Next.js 应用系统。


一、核心概念区分

在动手前,先厘清三个关键概念:

概念 说明
认证(Authentication) 验证“你是谁”——例如通过用户名/密码、OAuth 登录等方式确认用户身份。
会话管理(Session Management) 在用户登录后,持续跟踪其身份状态,通常通过 Cookie 或 Token 实现。
授权(Authorization) 决定“你能做什么”——例如普通用户只能查看自己的资料,管理员可删除内容。

二、整体架构设计

Next.js 推荐采用 服务端优先 的安全模型:

  • 表单提交Server Action(服务端执行)
  • 会话存储HttpOnly Cookie + JWT(或数据库)
  • 权限控制Middleware(乐观检查) + Data Access Layer(安全检查)

⚠️ 安全原则:所有敏感操作必须在服务端验证身份与权限,客户端仅用于 UI 展示。


三、Step 1:实现用户注册与登录(认证)

1. 创建注册表单(Client Component)

// app/signup/page.tsx
'use client'
import { signup } from '@/app/actions/auth'
import { useActionState } from 'react'

export default function SignupForm() {
  const [state, action, pending] = useActionState(signup, undefined)

  return (
    <form action={action}>
      <div>
        <label htmlFor="name">Name</label>
        <input name="name" />
      </div>
      {state?.errors?.name && <p>{state.errors.name[0]}</p>}

      <div>
        <label htmlFor="email">Email</label>
        <input name="email" type="email" />
      </div>
      {state?.errors?.email && <p>{state.errors.email[0]}</p>}

      <div>
        <label htmlFor="password">Password</label>
        <input name="password" type="password" />
      </div>
      {state?.errors?.password && (
        <ul>
          {state.errors.password.map(err => <li key={err}>- {err}</li>)}
        </ul>
      )}

      <button type="submit" disabled={pending}>
        Sign Up
      </button>
    </form>
  )
}

2. 定义表单验证(Zod Schema)

// lib/definitions.ts
import {
   
    z } from 'zod'

export const SignupFormSchema = z.object({
   
   
  name: z.string().min(2).trim(),
  email: z.string().email().trim(),
  password: z.string()
    .min(8)
    .regex(/[a-zA-Z]/)
    .regex(/[0-9]/)
    .regex(/[^a-zA-Z0-9]/)
})

export type FormState = {
   
   
  errors?: {
   
   
    name?: string[]
    email?: string[]
    password?: string[]
  }
  message?: string
}

3. 实现 Server Action(服务端逻辑)

// app/actions/auth.ts
'use server'
import {
   
    SignupFormSchema, FormState } from '@/lib/definitions'
import {
   
    db } from '@/lib/db'
import {
   
    users } from '@/lib/schema'
import bcrypt from 'bcrypt'
import {
   
    createSession } from '@/lib/session'
import {
   
    redirect } from 'next/navigation'

export 
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

golang学习记

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值