第 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,功能完善
相关推荐
子兮曰3 天前
jev-ultrafast 深度解析:7 秒订机票的浏览器 Agent 是如何炼成的
前端·后端·agent
子兮曰3 天前
Jev 爆发一周:7 秒 Agent 背后的 System One 生态与三场争议
前端·后端·ai编程
前端小万3 天前
写公众号赚了 3000 块后,我做了一款叫 "一键成稿" 的软件
前端·微信小程序
爱勇宝3 天前
ZCode 开源 24 小时:一份没有历史的账本,回答不了"有没有偷代码"
前端·后端·chatglm (智谱)
三十而立洋3 天前
Cookie 详解:从产生到安全,一次讲透
前端·javascript
卡布鲁3 天前
把一个 Vite + Vue3 应用塞进 qiankun (React + Umi3) 主站:十个坑的复盘
前端·javascript·react.js
汉堡大王95273 天前
Jev:不是聊天机器人, 而是一个智能 if 语句
前端·人工智能·后端
梦想很大很大3 天前
从运行事实到回归证据:Workrun 的 Telemetry 与 Evaluation 实践
前端·人工智能·后端
计算机魔术师3 天前
Meta Muse agent 接入 Shopify 的 Shop Pay 实现代理式购物
前端
沙蒿同学3 天前
我用 Go 搭了一条 AI Agent 流水线:从 1 张商品图到一整套淘宝详情页
前端·javascript·后端