第 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,功能完善
相关推荐
jay神1 分钟前
基于 Python + Flask + Vue 的校内求职互助平台
前端·vue.js·后端·python·flask·毕业设计
2501_940041747 分钟前
从跑酷到实时联机:5个能直接用的Web游戏开发需求
前端
RANxy12 分钟前
零基础全栈 React 入门(三):状态管理与事件处理
前端
Csvn14 分钟前
前端调试技巧
前端
右耳朵猫AI15 分钟前
React技术周刊 2026年第20周
前端·react.js·前端框架
问心无愧051316 分钟前
ctf show web入门58
前端·笔记
zzx2006__23 分钟前
JavaScript最终考核
开发语言·前端·javascript
用户44455436542628 分钟前
Android跑马灯控件
前端
光影少年37 分钟前
react全局状态、局部状态、服务端状态如何选型
前端·react.js·掘金·金石计划
甄心爱学习39 分钟前
【项目实训(个人10)】
开发语言·前端·javascript