JavaScript (Node.js) 中的授权与认证:完整指南

面向初学者的在线Python训练器

轻松学习Python,无需理论负担。在浏览器中直接解决带自动检查的实践任务,无需安装任何东西。

开始课程

JavaScript (Node.js) 中的授权与认证



在现代 Node.js Web 开发中,用户数据安全和访问控制是至关重要的任务。认证(身份验证)和授权(权限验证)是任何安全系统的两大支柱。在本文中,我们将探讨在 Node.js 平台上实现这些机制的关键工具和库。



基本概念

认证——验证用户身份的过程(通常通过登录名/密码、令牌或生物识别)。授权——确定经过认证的用户可以执行哪些操作以及访问哪些资源(角色、访问权限)。



Node.js 常用库



1. Passport.js —— 通用认证策略

Passport.js 是 Express 最流行的中间件库。它支持超过 500 种策略:本地(登录名/密码)、OAuth2(Google、Facebook、GitHub)、JWT 等。



const passport = require('passport');const LocalStrategy = require('passport-local').Strategy;

passport.use(new LocalStrategy( function(username, password, done) { User.findOne({ username: username }, function (err, user) { if (err) { return done(err); } if (!user) { return done(null, false, { message: '用户名无效' }); } if (!user.validPassword(password)) { return done(null, false, { message: '密码错误' }); } return done(null, user); }); }));

// 用户序列化与反序列化passport.serializeUser(function(user, done) { done(null, user.id);});

passport.deserializeUser(function(id, done) { User.findById(id, function(err, user) { done(err, user); });});


2. JSON Web Tokens (JWT) —— 无状态认证

jsonwebtoken 库允许创建和验证 JWT 令牌。这非常适合 REST API 和 SPA 应用。



const jwt = require('jsonwebtoken');const secretKey = process.env.JWT_SECRET;

// 登录时创建令牌const token = jwt.sign( { userId: user.id, role: user.role }, secretKey, { expiresIn: '24h' });

// 验证令牌的中间件function authMiddleware(req, res, next) { const authHeader = req.headers['authorization']; const token = authHeader && authHeader.split(' ')[1]; // Bearer TOKEN

if (!token) return res.status(401).json({ error: '未提供令牌' });

jwt.verify(token, secretKey, (err, decoded) => { if (err) return res.status(403).json({ error: '无效的令牌' }); req.user = decoded; next(); });}


3. bcrypt —— 安全密码哈希

切勿以明文形式存储密码!bcrypt 是加盐哈希的金标准。



const bcrypt = require('bcrypt');const saltRounds = 10;

// 注册时对密码进行哈希async function hashPassword(plainPassword) { const salt = await bcrypt.genSalt(saltRounds); const hash = await bcrypt.hash(plainPassword, salt); return hash;}

// 登录时验证密码async function checkPassword(plainPassword, hash) { return await bcrypt.compare(plainPassword, hash);}


4. express-session + connect-redis —— 会话管理

对于使用服务器端会话的传统 Web 应用,请结合使用 express-session 和 Redis 以实现扩展。



const session = require('express-session');const RedisStore = require('connect-redis')(session);

app.use(session({ store: new RedisStore({ client: redisClient }), secret: process.env.SESSION_SECRET, resave: false, saveUninitialized: false, cookie: { secure: process.env.NODE_ENV === 'production', // HTTPS httpOnly: true, maxAge: 24 * 60 * 60 * 1000 // 1 天 }}))

推荐