NodeJS使用JWT跨域身份验证方案详解
什么是JWT?
JWT(JSON Web Token)是一种基于JSON编码的轻量级的身份验证方式。它可以安全的用于通信双方之间传递信息,以验证发送方是否有权发送信息,并且可以保证接收方信息的完整性和真实性。 JWT由三部分组成,分别是header、payload和signature,而每一部分都是使用Base64编码形式的。
JWT的使用场景
- 在身份验证过程中传递信息(例如登录凭证)
- 为特定的资源授权(例如操作权限,访问权限等)
JWT工作流程
假设,在使用JWT验证的场景下,客户端发出请求向服务端获取被保护的资源,那么该验证过程会按照下面的流程进行。
- 客户端向服务器发送请求,携带JWT身份信息。
- 服务器接收到请求后,验证JWT身份信息是否正确。
- 如果验证成功,服务器会返回被保护的资源;否则,服务器不会返回被保护的资源。
JWT使用方法
- 安装jsonwebtoken模块
npm install jsonwebtoken
- 引入jsonwebtoken模块
const jwt = require('jsonwebtoken');
- 创建JWT
// jwt.sign(payload, secretOrPrivateKey, [options, callback])
// payload - 负载,用来存放需要安全传输的信息
// secretOrPrivateKey - 加密所需要的密钥,可以是字符串,也可以是缓存格式的私密密码,如果使用默认加密算法是HSA则用字符串
// options - 生成的Token的一些选项参数
// callback - 密钥所在的回调函数
jwt.sign({ foo: 'bar' }, 'secretKey', { expiresIn: '2h' }, function(err, token) {
console.log(token);
});
- 验证JWT
// jwt.verify(token, secretOrPublicKey, [options, callback])
// token - 需要验证的token数据
// secretOrPublicKey - 负责生成加密的secretKey或者公钥
// options - 验证的一些选项参数
// callback - 验证过程中所需的回调
jwt.verify(token, 'secretKey', function(err, decoded) {
console.log(decoded.foo) //bar
});
JWT跨域身份验证实现示例
为了方便示例说明,我们假定实现一个网站,该网站请求资源需要登录。前端使用Ajax发送请求,后端使用NodeJS构建。
- 在前端,首先需要在登录成功后创建JWT,然后每次请求时携带JWT发送到服务端。
//登录后创建JWT,存储到localStorage中
axios.post('/login', { username: 'admin', password: 'password' })
.then((response) => {
const token = response.token;
localStorage.setItem('token', token);
});
//每次请求时携带JWT发送到服务端
axios.get('/protected', { headers: { Authorization: `Bearer ${localStorage.getItem('token')}` }})
.then((response) => {
console.log(response.data);
});
- 在服务端,首先需要验证JWT的有效性,如果验证成功则给予授权,返回请求的资源;否则则返回401错误。
const express = require('express');
const jwt = require('jsonwebtoken');
const app = express();
const port = 3000;
app.use(express.json());
//登录验证
app.post('/login', (req, res) => {
//验证账号密码逻辑省略,模拟成功返回token
const token = jwt.sign({ username: 'admin' }, 'secretKey', { expiresIn: '2h' });
res.send({ token });
});
//被保护的资源, 需要登录验证
app.get('/protected', verifyToken, (req, res) => {
res.send('success');
});
//验证jwt合法性的中间件
function verifyToken(req, res, next) {
const bearerHeader = req.headers['authorization'];
if (typeof bearerHeader !== 'undefined') {
const bearerToken = bearerHeader.split(' ')[1];
req.token = bearerToken;
jwt.verify(req.token, 'secretKey', (err, authData) => {
if (err) {
res.sendStatus(401);
} else {
next();
}
});
} else {
res.sendStatus(401);
}
}
app.listen(port, () => {
console.log(`Example app listening at http://localhost:${port}`);
});
这样,前端每次请求资源时都会携带JWT,服务端通过校验JWT的有效性给予授权,返回被保护的资源。
本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:NodeJS使用JWT跨域身份验证方案详解 - Python技术站