在现代前端开发中,RESTful API 是非常普遍的一种方式来实现前后端数据交互。而对于一些需要安全性保障的应用,我们需要对 RESTful API 进行认证。
认证是指验证用户身份的过程。在 RESTful API 中,认证可以通过传递令牌来实现。令牌是一种由服务器颁发的字符串,它代表了用户的身份,并且具有一定的时效性。当用户通过认证后,服务器会将令牌返回给客户端,客户端在后续的请求中需要带上这个令牌来证明自己的身份。
如何管理认证信息
在 RESTful API 中,管理认证信息通常有两种方式:使用 HTTP 基本认证和使用 JSON Web Token(JWT)。
HTTP 基本认证
HTTP 基本认证是指在 HTTP 头中传递用户名和密码。在客户端发送请求时,需要在 HTTP 头中添加 Authorization 字段。该字段的值为 Basic base64(username:password)。
例如,如果用户名为 "admin",密码为 "123456",那么 Authorization 字段的值应该为 "Basic YWRtaW46MTIzNDU2"。
在服务器端,需要对传递过来的用户名和密码进行验证,如果验证通过,则返回令牌给客户端。在客户端下一次请求时,需要在 HTTP 头中添加 Authorization 字段,并且该字段的值为服务器返回的令牌。
使用 HTTP 基本认证的缺点是,用户名和密码是明文传递的,容易被拦截和窃取。因此,我们通常不建议使用 HTTP 基本认证。
JSON Web Token(JWT)
JSON Web Token(JWT)是一种基于 JSON 的开放标准,用于在网络应用间传递声明。JWT 由三部分组成:头部(Header)、载荷(Payload)和签名(Signature)。
头部通常由两部分组成:令牌类型和加密算法。例如,一个 JWT 的头部可能是这样的:
{
"typ": "JWT",
"alg": "HS256"
}载荷是 JWT 的主体,用于存储一些声明信息,例如用户 ID、用户名、角色等。例如,一个包含用户 ID 的 JWT 可以是这样的:
{
"sub": "1234567890",
"name": "John Doe",
"iat": 1516239022
}签名是 JWT 的最后一部分,用于验证 JWT 的完整性。签名通常由头部、载荷和一个秘钥组成。在服务器端,需要使用同样的秘钥对 JWT 进行验证,以确保它没有被篡改过。
使用 JWT 的好处是,它不需要在每次请求中传递用户名和密码,而是使用令牌来代替。令牌是由服务器颁发的,所以不容易被伪造。同时,JWT 支持自定义载荷,在载荷中存储用户的一些信息,可以减少服务器的查询次数,提高性能。
示例代码
下面是一个使用 JWT 认证的示例代码:
// www.javascriptcn.com code example
// 生成 JWT
const jwt = require('jsonwebtoken')
const token = jwt.sign({ id: '123456' }, 'secret', { expiresIn: '1h' })
// 在请求头中添加 Authorization 字段
const headers = {
Authorization: `Bearer ${token}`
}
// 验证 JWT
const verifyJwt = (req, res, next) => {
const token = req.headers.authorization.split(' ')[1]
jwt.verify(token, 'secret', (err, decoded) => {
if (err) {
res.status(401).json({ message: 'Invalid token' })
} else {
req.user = decoded
next()
}
})
}
// 访问受保护的路由
app.get('/protected', verifyJwt, (req, res) => {
res.json({ message: 'Access granted' })
})在上面的代码中,我们使用了 jsonwebtoken 库来生成和验证 JWT。在生成 JWT 时,我们传递了一个载荷,其中包含了用户的 ID。在验证 JWT 时,我们使用了一个中间件函数 verifyJwt,它会在请求头中查找 Authorization 字段,并且验证 JWT 的有效性。如果验证通过,我们会将解码后的用户信息存储在 req.user 中,供后续的处理函数使用。
来源:JavaScript中文网 ,转载请注明来源 https://www.javascriptcn.com/post/67d91582a941bf713408ed5a