JWT全面解读和详细使用步骤
什么是JWT?
JWT(JSON Web Token)是用于身份验证和授权的开放标准(RFC 7519),根据规范,JWT由三部分组成:头部(header)、荷载(payload)和签名(signature)。
头部
头部包含两个元素:令牌类型(通常是JWT)和所使用的签名算法(例如HMAC SHA256或RSA)。
使用json表示:
{
"alg": "HS256",
"typ": "JWT"
}
荷载
荷载包含需要传输的信息,如用户ID、用户名、角色、权限等信息。
使用json表示:
{
"sub": "1234567890",
"name": "Alice",
"iat": 1516239022
}
在上面的数据中,“sub”表示主题(subject),“name”表示姓名,“iat”表示签发时间(Issued At),数字都是Unix时间戳。
签名
签名是将头部和荷载签名后的结果,保证数据的完整性和不可篡改性。签名需要使用头部中指定的算法进行加密计算。
JWT的使用流程
- 用户登录,将登录信息发送到服务器。
- 服务器验证用户信息是否正确,如果正确,生成JWT并返回给用户。
- 用户携带JWT请求资源。
- 服务器需要验证JWT的合法性,检查签名和荷载信息是否完整,从而确认用户身份。
JWT的优势
- 不需要在服务端存储会话信息,方便扩展和分布式部署。
- 使用数字签名,保证数据的完整性和不可篡改性。
- 可以设置过期时间,增强安全性。
- 使用标准化的格式,易于处理和交换信息。
JWT的缺点
- 信息放在荷载中,影响传输效率。
- 一旦签发,无法撤回,除非等到过期时间。
- 一旦密钥泄露,攻击者可伪造JWT获取访问权限。
JWT的使用步骤
- 安装jsonwebtoken:npm install jsonwebtoken --save
- 在服务器端使用jsonwebtoken生成JWT:
const jwt = require('jsonwebtoken');
const secret = 'thisisasecret';
const payload = { sub: '1234567890', name: 'Alice', iat: Math.floor(Date.now() / 1000) };
const token = jwt.sign(payload, secret, { expiresIn: '1h' });
console.log(token);
代码中,使用jsonwebtoken模块生成JWT,需要传入荷载、密钥和过期时间等参数,返回生成的JWT。
- 在客户端使用JWT:
const xhr = new XMLHttpRequest();
const token = 'xxxxx'; // 从服务器获取到的JWT
xhr.open('GET', 'url');
xhr.setRequestHeader('Authorization', `Bearer ${token}`);
xhr.send();
代码中,使用XMLHttpRequest请求资源,需要将JWT放在请求头的Authorization字段中,格式为Bearer \
示例一:Express使用JWT实现登录认证
const express = require('express');
const jwt = require('jsonwebtoken');
const users = [{ id: 1, name: 'Alice', password: 'alicepassword' }];
const app = express();
const secret = 'thisisasecret';
app.use(express.json());
app.post('/login', (req, res) => {
const { name, password } = req.body;
const user = users.find(u => u.name === name && u.password === password);
if (user) {
const payload = { id: user.id, name: user.name };
const token = jwt.sign(payload, secret, { expiresIn: '1h' });
res.json({ token });
} else {
res.status(401).json({ message: 'Invalid username or password' });
}
});
const authHandler = (req, res, next) => {
const header = req.headers.authorization;
if (header) {
const token = header.split(' ')[1];
jwt.verify(token, secret, (err, payload) => {
if (err) {
res.status(403).json({ message: 'Failed to authenticate token' });
} else {
req.user = payload;
next();
}
});
} else {
res.status(401).json({ message: 'No token provided' });
}
};
app.get('/protected', authHandler, (req, res) => {
res.json({
message: `Welcome ${req.user.name} to the protected resource`,
});
});
app.listen(3000, () => {
console.log('Server started on port 3000');
});
代码中使用Express框架实现登录认证功能,在路由‘/login’中当用户输入正确的用户名和密码时,服务器会生成JWT并返回给客户端。用户访问路由‘/protected’时,需要经过authHandler中间件,检查JWT的合法性,如果验证成功,则允许用户访问受保护的资源。
示例二:使用Axios发送带有JWT的请求
const axios = require('axios');
const jwt = require('jsonwebtoken');
const secret = 'thisisasecret';
const payload = { sub: '1234567890', name: 'Alice', iat: Math.floor(Date.now() / 1000) };
const token = jwt.sign(payload, secret, { expiresIn: '1h' });
const config = {
headers: {
'Authorization': `Bearer ${token}`
}
};
axios.get('url', config)
.then(response => {
console.log(response.data);
})
.catch(error => {
console.error(error);
});
代码中使用Axios发送GET请求时,在请求头中添加JWT,格式同上,Axios会自动将对象转换为JSON格式并发送请求。如果成功,则输出响应数据;如果失败,则输出错误信息。
本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:JWT全面解读和详细使用步骤 - Python技术站