Node.js 中的 Token 认证机制详解

文章目录

  • Node.js 中的 Token 认证机制详解
    • 1. Token 认证基础
      • 1.1 什么是 Token 认证?
      • 1.2 Token 认证流程
    • 2. JWT (JSON Web Token) 实现
      • 2.1 安装依赖
      • 2.2 生成 Token
      • 2.3 验证 Token 中间件
    • 3. 完整实现示例
      • 3.1 登录接口
      • 3.2 受保护的路由
    • 4. Token 安全最佳实践
    • 5. Token 刷新机制
    • 6. 实际应用中的常见问题
      • 6.1 如何注销 Token?
      • 6.2 如何防止 CSRF 攻击?
    • 7. 性能优化建议

Node.js 中的 Token 认证机制详解

Token(令牌)是现代 Web 应用中常用的身份验证机制,相比传统的 Session 认证更加灵活和安全。下面我将详细介绍在 Node.js 中实现 Token 认证的完整方案。

1. Token 认证基础

1.1 什么是 Token 认证?

Token 认证是一种无状态的认证机制,服务器在用户登录后生成一个加密的字符串(Token)返回给客户端,客户端在后续请求中携带这个 Token 来证明身份。

1.2 Token 认证流程

Client Server 登录请求(用户名/密码) 验证成功,返回Token 携带Token的API请求 验证Token,返回数据 Client Server

2. JWT (JSON Web Token) 实现

2.1 安装依赖

npm install jsonwebtoken

2.2 生成 Token

const jwt = require('jsonwebtoken');
const secret = 'your-secret-key'; // 应该使用环境变量存储

function generateToken(user) {
    return jwt.sign(
        {
            userId: user.id,
            username: user.username,
            role: user.role
        },
        secret,
        { expiresIn: '1h' } // Token有效期1小时
    );
}

2.3 验证 Token 中间件

function authenticateToken(req, res, next) {
    const authHeader = req.headers['authorization'];
    const token = authHeader && authHeader.split(' ')[1]; // Bearer TOKEN
    
    if (!token) return res.sendStatus(401); // 未提供Token
    
    jwt.verify(token, secret, (err, user) => {
        if (err) return res.sendStatus(403); // Token无效或过期
        req.user = user;
        next();
    });
}

3. 完整实现示例

3.1 登录接口

const express = require('express');
const app = express();
app.use(express.json());

// 模拟用户数据
const users = [
    { id: 1, username: 'admin', password: 'admin123', role: 'admin' },
    { id: 2, username: 'user', password: 'user123', role: 'user' }
];

app.post('/login', (req, res) => {
    const { username, password } = req.body;
    
    // 查找用户
    const user = users.find(u => 
        u.username === username && u.password === password
    );
    
    if (!user) {
        return res.status(401).json({ error: '用户名或密码错误' });
    }
    
    // 生成Token
    const token = generateToken(user);
    
    res.json({ 
        message: '登录成功',
        token,
        user: {
            id: user.id,
            username: user.username,
            role: user.role
        }
    });
});

3.2 受保护的路由

app.get('/protected', authenticateToken, (req, res) => {
    res.json({ 
        message: '这是受保护的内容',
        user: req.user 
    });
});

4. Token 安全最佳实践

安全措施 实现方式 重要性
使用 HTTPS 部署 SSL 证书 ★★★★★
设置合理有效期 expiresIn 参数 ★★★★☆
使用强密钥 复杂密钥,定期更换 ★★★★★
存储安全 前端使用 HttpOnly Cookie ★★★★☆
黑名单机制 注销的 Token 加入黑名单 ★★★☆☆

5. Token 刷新机制

// 生成刷新Token
function generateRefreshToken(user) {
    return jwt.sign(
        { userId: user.id },
        secret + 'refresh', // 使用不同的密钥
        { expiresIn: '7d' } // 较长有效期
    );
}

// 刷新Token接口
app.post('/refresh-token', (req, res) => {
    const { refreshToken } = req.body;
    
    jwt.verify(refreshToken, secret + 'refresh', (err, payload) => {
        if (err) return res.sendStatus(403);
        
        const user = users.find(u => u.id === payload.userId);
        if (!user) return res.sendStatus(404);
        
        const newToken = generateToken(user);
        res.json({ token: newToken });
    });
});

6. 实际应用中的常见问题

6.1 如何注销 Token?

JWT 本身是无状态的,要实现注销可以考虑:

  1. 短期 Token 有效期
  2. Token 黑名单
  3. 客户端主动删除 Token

6.2 如何防止 CSRF 攻击?

即使使用 Token 也需要注意 CSRF 防护:

  1. 使用 SameSite Cookie 属性
  2. 添加 CSRF Token
  3. 检查 Origin 和 Referer 头部

7. 性能优化建议

  1. 减少 Token 体积:只包含必要的信息
  2. 预编译正则:验证中间件中的正则表达式
  3. 异步验证:大量用户时考虑异步验证
  4. 缓存机制:频繁验证的用户可以缓存结果

通过以上实现,您可以在 Node.js 应用中构建一个安全、高效的 Token 认证系统。

你可能感兴趣的:(node.js,vim,编辑器,有问必答)