Nodejs 做REST接口,express基于cookie的session不能用了。有什么推荐的?

Nodejs 做REST接口,express基于cookie的session不能用了。有什么推荐的?

做REST接口,express基于cookie的session不能用了。有什么推荐的?

3 回复

当然可以!如果你在使用 Express 做 REST 接口时发现基于 cookie 的 session 不再适用,可能是因为你希望避免将敏感信息存储在客户端。在这种情况下,可以考虑使用 JWT(JSON Web Tokens)来处理身份验证和授权。

JWT 是一种开放标准 (RFC 7519),用于在网络应用环境间安全地将信息作为 JSON 对象传输。它可以在用户认证、信息交换等方面提供很好的安全性。

以下是一个简单的示例,展示如何使用 JWT 来处理 REST API 的身份验证:

安装依赖

首先,你需要安装 jsonwebtokenexpress-jwt 包:

npm install jsonwebtoken express-jwt

示例代码

1. 设置 JWT 中间件

const express = require('express');
const jwt = require('jsonwebtoken');
const app = express();

// 设置密钥
const secretKey = 'your_secret_key';

// 创建一个中间件来验证 JWT
app.use(express.json());
app.use((req, res, next) => {
    const token = req.headers['authorization'];
    if (!token) return res.status(403).send({ auth: false, message: 'No token provided.' });

    jwt.verify(token, secretKey, (err, decoded) => {
        if (err) return res.status(500).send({ auth: false, message: 'Failed to authenticate token.' });
        
        // 如果验证成功,将解码后的 token 存储在请求对象中
        req.userId = decoded.id;
        next();
    });
});

// 示例路由
app.post('/login', (req, res) => {
    const user = { id: 1, name: 'John Doe' };
    const token = jwt.sign({ id: user.id }, secretKey, { expiresIn: 86400 }); // 有效期为24小时
    res.status(200).send({ auth: true, token });
});

app.get('/protected', (req, res) => {
    res.status(200).send({ message: 'This is a protected route.', userId: req.userId });
});

app.listen(3000, () => console.log('Server running on port 3000'));

解释

  1. JWT 签发:当用户登录时,我们生成一个 JWT 并将其发送给客户端。
  2. JWT 验证:在每个需要保护的路由前添加中间件,该中间件会检查请求头中的 Authorization 字段,并验证 JWT 是否有效。
  3. 解码后的数据:如果 JWT 验证成功,我们将解码后的用户 ID 存储在请求对象中,以便后续处理。

这种方式不仅避免了将敏感信息存储在客户端,还提供了更好的安全性,因为 JWT 可以包含用户的身份信息并进行加密。


登录成功后自己生成token和对应的用户信息,存到redis或memcached。在http route到业务处理之前进行token的验证,通过验证后把token对应的用户信息保存到request对象里,方便后面业务处理代码使用。推荐使用redis或memcached一个是因为他们是速度很快很稳定的内存数据服务器,自身带有ttl管理。二是把session信息存到外部服务器便于将来扩展部署。

在现代Web开发中,使用JWT(JSON Web Tokens)是一种更推荐的方法来处理用户认证和会话管理,特别是在构建REST API时。与传统的基于Cookie的Session相比,JWT更加灵活且易于扩展到分布式系统中。

为什么推荐JWT?

  1. 无状态性:服务器不需要存储会话信息,可以极大地提高系统的可扩展性。
  2. 跨域支持:JWT可以在不同域之间传递,这对于前端应用来说非常方便。
  3. 安全性:即使token被拦截,攻击者也无法直接利用它,除非他们拥有私钥。

示例代码

以下是一个简单的Express应用示例,展示了如何使用JWT进行认证:

安装依赖

npm install express jsonwebtoken body-parser

创建一个基本的Express应用

const express = require('express');
const jwt = require('jsonwebtoken');
const bodyParser = require('body-parser');

const app = express();
app.use(bodyParser.json());

// 密钥
const secretKey = 'your_secret_key';

// 模拟数据库中的用户数据
const users = [
    { id: 1, username: 'admin', password: 'password' }
];

// 登录路由
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({ message: 'Invalid credentials' });
    }

    // 生成JWT
    const token = jwt.sign({ id: user.id }, secretKey, { expiresIn: '1h' });

    res.json({ token });
});

// 受保护的路由
app.get('/protected', verifyToken, (req, res) => {
    res.json({ message: 'This is a protected route' });
});

// JWT验证中间件
function verifyToken(req, res, next) {
    const token = req.headers['authorization'];
    if (!token) {
        return res.status(403).send({ message: 'No token provided' });
    }

    jwt.verify(token, secretKey, (err, decoded) => {
        if (err) {
            return res.status(401).send({ message: 'Failed to authenticate token' });
        }
        req.userId = decoded.id;
        next();
    });
}

app.listen(3000, () => {
    console.log('Server running on port 3000');
});

总结

在这个示例中,我们创建了一个登录接口来生成JWT,并在受保护的路由上使用JWT验证中间件。这种方式避免了服务器端存储会话状态的需求,使得应用更加灵活和可扩展。

回到顶部