mcpField
J
jwt-authentication

jwt-authentication

github.com/pluginagentmarketplace安全2226 次安装42 周前更新
代码仓库

关于 jwt-authentication

为 Node.js 应用添加 JWT 身份验证的学习与实现指南,涵盖注册、登录和受保护路由,也介绍令牌刷新、基于角色的访问控制等模式。

主要功能

  1. 01生成并验证 JWT
  2. 02注册用户并验证密码
  3. 03用中间件保护路由
  4. 04刷新令牌并管理有效期
  5. 05实现基于角色的访问控制

适用场景

  1. 01为 Node.js REST API 添加身份验证
  2. 02使用 JWT 保护应用路由
  3. 03构建令牌刷新和访问控制流程

安装

复制下面的命令,在终端中运行。

$npx skills add https://github.com/pluginagentmarketplace/custom-plugin-nodejs --skill jwt-authentication

安装后在 Claude Code 中输入/jwt-authentication确认已加载。

包含的文件

除 SKILL.md 外,安装时一起下载的参考资料和脚本。

assets/
config.yaml
references/
GUIDE.md
scripts/
helper.py

详细介绍

JWT 身份验证技能

使用 JSON Web Token 在 Node.js 应用中实现安全、可扩展的身份验证。

快速开始

JWT 身份验证分为 4 个步骤:

  1. 安装 - npm install jsonwebtoken bcryptjs
  2. 注册 - 对密码进行哈希处理、创建用户、生成令牌
  3. 登录 - 验证密码、生成令牌
  4. 保护 - 在中间件中验证令牌

核心概念

生成 JWT
const jwt = require('jsonwebtoken');

function generateToken(userId) {
  return jwt.sign(
    { id: userId },
    process.env.JWT_SECRET,
    { expiresIn: '1h' }
  );
}

function generateRefreshToken(userId) {
  return jwt.sign(
    { id: userId },
    process.env.JWT_REFRESH_SECRET,
    { expiresIn: '7d' }
  );
}
用户注册
const bcrypt = require('bcryptjs');

async function register(req, res) {
  const { email, password, name } = req.body;

  // Check if user exists
  const existingUser = await User.findOne({ email });
  if (existingUser) {
    return res.status(409).json({ error: 'User already exists' });
  }

  // Hash password
  const hashedPassword = await bcrypt.hash(password, 10);

  // Create user
  const user = await User.create({
    email,
    password: hashedPassword,
    name
  });

  // Generate tokens
  const accessToken = generateToken(user._id);
  const refreshToken = generateRefreshToken(user._id);

  res.status(201).json({
    user: { id: user._id, email, name },
    accessToken,
    refreshToken
  });
}
用户登录
async function login(req, res) {
  const { email, password } = req.body;

  // Find user
  const user = await User.findOne({ email });
  if (!user) {
    return res.status(401).json({ error: 'Invalid credentials' });
  }

  // Verify password
  const isValid = await bcrypt.compare(password, user.password);
  if (!isValid) {
    return res.status(401).json({ error: 'Invalid credentials' });
  }

  // Generate tokens
  const accessToken = generateToken(user._id);
  const refreshToken = generateRefreshToken(user._id);

  res.json({
    user: { id: user._id, email: user.email },
    accessToken,
    refreshToken
  });
}
身份验证中间件
async function authenticate(req, res, next) {
  try {
    // Get token from header
    const authHeader = req.headers.authorization;
    if (!authHeader || !authHeader.startsWith('Bearer ')) {
      return res.status(401).json({ error: 'No token provided' });
    }

    const token = authHeader.split(' ')[1];

    // Verify token
    const decoded = jwt.verify(token, process.env.JWT_SECRET);

    // Get user
    const user = await User.findById(decoded.id).select('-password');
    if (!user) {
      return res.status(401).json({ error: 'User not found' });
    }

    req.user = user;
    next();
  } catch (error) {
    res.status(401).json({ error: 'Invalid token' });
  }
}

// Usage
router.get('/profile', authenticate, getProfile);

学习路径

初级(1-2 周)
  • ✅ 了解 JWT 结构
  • ✅ 实现注册/登录
  • ✅ 创建身份验证中间件
  • ✅ 保护路由
中级(3-4 周)
  • ✅ 刷新令牌流程
  • ✅ 基于角色的访问控制
  • ✅ 密码重置流程
  • ✅ 令牌黑名单
高级(5-6 周)
  • ✅ OAuth 集成
  • ✅ 双重身份验证
  • ✅ 会话管理
  • ✅ 安全最佳实践

高级模式

基于角色的访问控制
const authorize = (...roles) => {
  return (req, res, next) => {
    if (!req.user) {
      return res.status(401).json({ error: 'Not authenticated' });
    }

    if (!roles.includes(req.user.role)) {
      return res.status(403).json({ error: 'Insufficient permissions' });
    }

    next();
  };
};

// Usage
router.delete('/users/:id',
  authenticate,
  authorize('admin', 'moderator'),
  deleteUser
);
令牌刷新
async function refreshAccessToken(req, res) {
  const { refreshToken } = req.body;

  try {
    const decoded = jwt.verify(refreshToken, process.env.JWT_REFRESH_SECRET);

    // Verify refresh token exists in database
    const stored = await RefreshToken.findOne({
      token: refreshToken,
      userId: decoded.id
    });

    if (!stored) {
      return res.status(401).json({ error: 'Invalid refresh token' });
    }

    // Generate new access token
    const accessToken = generateToken(decoded.id);

    res.json({ accessToken });
  } catch (error) {
    res.status(401).json({ error: 'Token refresh failed' });
  }
}
密码重置流程
async function requestPasswordReset(req, res) {
  const { email } = req.body;
  const user = await User.findOne({ email });

  if (!user) {
    return res.status(404).json({ error: 'User not found' });
  }

  // Generate reset token (short expiry)
  const resetToken = jwt.sign(
    { id: user._id, purpose: 'reset' },
    process.env.JWT_SECRET,
    { expiresIn: '15m' }
  );

  // Send email with reset link
  await sendResetEmail(user.email, resetToken);

  res.json({ message: 'Reset email sent' });
}

async function resetPassword(req, res) {
  const { token, newPassword } = req.body;

  try {
    const decoded = jwt.verify(token, process.env.JWT_SECRET);

    if (decoded.purpose !== 'reset') {
      return res.status(400).json({ error: 'Invalid token' });
    }

    const hashedPassword = await bcrypt.hash(newPassword, 10);
    await User.findByIdAndUpdate(decoded.id, { password: hashedPassword });

    res.json({ message: 'Password reset successful' });
  } catch (error) {
    res.status(400).json({ error: 'Invalid or expired token' });
  }
}

安全最佳实践

  • ✅ 使用强 JWT 密钥(32 个以上字符,随机生成)
  • ✅ 访问令牌设置较短的有效期(15 分钟 - 1 小时)
  • ✅ 刷新令牌设置较长的有效期(7 天 - 30 天)
  • ✅ 将刷新令牌存储在数据库中
  • ✅ 使用 bcrypt 对密码进行哈希处理(10 轮以上)
  • ✅ 在生产环境中使用 HTTPS
  • ✅ 实施速率限制
  • ✅ 验证所有输入
  • ✅ 不要在 JWT 负载中存储敏感数据

JWT 结构

header.payload.signature

Header (base64):
{
  "alg": "HS256",
  "typ": "JWT"
}

Payload (base64):
{
  "id": "user123",
  "iat": 1516239022,
  "exp": 1516242622
}

Signature:
HMACSHA256(
  base64UrlEncode(header) + "." + base64UrlEncode(payload),
  secret
)

常见 JWT 声明

  • iss - 颁发者
  • sub - 主体(用户 ID)
  • aud - 受众
  • exp - 过期时间
  • iat - 签发时间
  • nbf - 生效时间

适用场景

以下情况适合使用 JWT 身份验证:

  • 构建无状态 REST API
  • 需要可扩展性(无需服务端会话)
  • 移动应用身份验证
  • 微服务架构
  • 单点登录(SSO)

相关技能

  • Express REST API(保护 API 端点)
  • 数据库集成(存储用户)
  • 测试与调试(测试身份验证流程)
  • 性能优化(令牌缓存)

资源

评论

支持 Markdown