第 8 章:认证与授权(Authentication & Authorization)

第 8 章:认证与授权(Authentication & Authorization)


8.1 认证 vs 授权

  • 认证(Authentication) :确认用户身份,比如是否已登录。
  • 授权(Authorization) :确认用户是否有权限执行某些操作,比如是否是管理员。

8.2 认证方式概览

认证方式 优点 缺点
Cookie Session 简单易用 需手动处理加密、过期等
JWT Token 前后端分离友好 容易被盗用,需安全存储
NextAuth.js 快速集成多平台登录 定制化复杂

📄 pages/api/login.js

js 复制代码
export default function handler(req, res) {
  const { username, password } = req.body;

  if (username === 'admin' && password === '123456') {
    res.setHeader('Set-Cookie', 'token=admin-token; Path=/; HttpOnly');
    res.status(200).json({ success: true });
  } else {
    res.status(401).json({ success: false, error: 'Invalid credentials' });
  }
}

📄 pages/api/logout.js

js 复制代码
export default function handler(req, res) {
  res.setHeader('Set-Cookie', 'token=; Path=/; Max-Age=0');
  res.status(200).json({ success: true });
}

📄 页面中获取 cookie(服务端)

js 复制代码
// pages/dashboard.js
export async function getServerSideProps({ req }) {
  const token = req.cookies.token;

  if (token !== 'admin-token') {
    return {
      redirect: {
        destination: '/login',
        permanent: false,
      },
    };
  }

  return { props: {} };
}

8.4 JWT 登录认证(推荐 API 模式)

📦 安装依赖:

bash 复制代码
npm install jsonwebtoken

📄 lib/jwt.js

js 复制代码
import jwt from 'jsonwebtoken';

const SECRET = 'your-secret-key';

export const signToken = (payload) =>
  jwt.sign(payload, SECRET, { expiresIn: '1h' });

export const verifyToken = (token) =>
  jwt.verify(token, SECRET);

📄 pages/api/login.js

js 复制代码
import { signToken } from '../../lib/jwt';

export default function handler(req, res) {
  const { username, password } = req.body;

  if (username === 'admin' && password === '123456') {
    const token = signToken({ username });
    res.setHeader('Set-Cookie', `token=${token}; Path=/; HttpOnly`);
    res.status(200).json({ success: true });
  } else {
    res.status(401).json({ error: 'Invalid credentials' });
  }
}

📄 验证 Token 示例

js 复制代码
import { verifyToken } from '../../lib/jwt';

export async function getServerSideProps({ req }) {
  const { token } = req.cookies;

  try {
    const user = verifyToken(token);
    return { props: { user } };
  } catch (e) {
    return {
      redirect: {
        destination: '/login',
        permanent: false,
      },
    };
  }
}

8.5 使用 NextAuth.js 快速集成认证(推荐方式)

📦 安装:

bash 复制代码
npm install next-auth

📄 pages/api/auth/[...nextauth].js

js 复制代码
import NextAuth from 'next-auth';
import CredentialsProvider from 'next-auth/providers/credentials';

export default NextAuth({
  providers: [
    CredentialsProvider({
      name: 'Credentials',
      credentials: {
        username: { label: '用户名', type: 'text' },
        password: { label: '密码', type: 'password' },
      },
      async authorize(credentials) {
        const { username, password } = credentials;

        if (username === 'admin' && password === '123456') {
          return { id: 1, name: 'admin' };
        }
        return null;
      },
    }),
  ],
  pages: {
    signIn: '/login',
  },
  session: {
    strategy: 'jwt',
  },
});

📄 页面中获取会话:

js 复制代码
import { useSession, signOut } from 'next-auth/react';

export default function Dashboard() {
  const { data: session } = useSession();

  if (!session) return <p>未登录</p>;

  return (
    <div>
      <p>欢迎,{session.user.name}</p>
      <button onClick={() => signOut()}>退出</button>
    </div>
  );
}

📄 SSR 中获取会话:

js 复制代码
import { getSession } from 'next-auth/react';

export async function getServerSideProps(context) {
  const session = await getSession(context);

  if (!session) {
    return {
      redirect: {
        destination: '/login',
        permanent: false,
      },
    };
  }

  return { props: { session } };
}

8.6 保护页面与接口

场景 推荐方式
页面访问保护 使用 getServerSideProps 检查 cookie/JWT/session
接口保护 在 API 路由中验证 cookie 或 token
中间件权限拦截 在 middleware.js 中基于 cookie 重定向
客户端使用 useSession() 或全局状态管理

✅ 小结

认证方式 推荐场景 特点
Cookie Session SSR 项目 / 简单登录系统 快速简单,适合小项目
JWT Token 前后端分离、多端兼容 灵活易扩展,可搭配移动端
NextAuth.js 快速上线,支持社交登录 内置 Google/GitHub 等 OAuth,功能完善
相关推荐
jerrywus1 分钟前
我用 GPT-6.1-sol 做了台会讲解的 3D 售货机:60 罐饮料,一口没喝上
前端·agent·claude
孟陬1 小时前
Foobar 技术周刊#159:当看不懂代码时,如何高效排障调试。脏页陷阱:一条只读查询,写入数 TB 数据。推测解码:大模型加速利器
前端·人工智能·后端
Zhao-Jichao1 小时前
AI Prompting for Everyone 课程笔记 - P17 图像生成 Imaging Generation
前端
Highcharts.js2 小时前
智能数据分析组件Orbit 正式发布与快速上手体验教程
前端·人工智能·信息可视化·数据分析系统·highcharts·orbit·智能可视化
螺丝钉tina3 小时前
[Playwright ][16]Playwright + TypeScript API 自动化测试实战:API测试
前端·javascript·typescript
小天源3 小时前
智叟云集系统 · 架构与职责分层
服务器·前端·数据库
Highcharts.js5 小时前
React 中原生支持使用 JSX 组件配置自定义表格 Highcharts Grid
前端·javascript·react.js·前端框架·jsx·highcharts·自定义表格
薛定谔的猫-菜鸟程序员5 小时前
Electron开发超详细教程(从入门到放弃)
前端·javascript·electron
最强小杰6 小时前
DeepSeek V4 Flash + Codex CLI 接入教程:原生 Responses API 适配,从配置到跑通收藏这篇就够了(2026)
java·前端·python·ai
静水leo6 小时前
使用 Whistle 拦截接口并模拟后端响应
前端