使用 JSON Web Token 保护您的 Node.js API
介绍
它是如何运作的?
我们将要建造什么?
config.js
设置身份验证系统
设置中间件
结论
介绍
如今,REST(表述性状态转移)凭借其简洁的语法和灵活性,已成为Web架构中最常用的风格。REST允许用户扩展其应用程序,因为来自不同前端平台的客户端可以使用HTTP协议轻松地向服务器发送请求,并交换以JSON或XML格式编码的数据。
尽管 RESTful 架构具备诸多特性,但它仍然存在一些问题,尤其是在安全性方面。
用于保护 RESTful API 的众多安全方法之一是基于令牌的身份验证。
那么,什么是基于令牌的身份验证?
咱们简单点儿吧 :))
基于令牌的身份验证系统的基本概念很简单。
允许用户使用用户名和密码获取令牌,从而无需每次都使用其自然凭据即可访问特定资源。
用户获得令牌后,即可使用该令牌在一段时间内访问远程站点服务器上的特定资源。
它是如何运作的?
使用 JWT 的过程包含 6 个步骤。
1. 使用凭据进行身份验证
2. 身份验证成功后,服务器会生成一个包含 JSON Web 令牌的随机字符串。
3. 将令牌返回给客户端
4. 将令牌存储在客户端
5. 客户端向服务器发送的每个 HTTP 请求中都包含令牌
6. 服务器检查令牌是否有效,并授予对指定资源的访问权限。
我们将要建造什么?
在本文中,我们将使用 Node.js 和 Express.js 构建一个 API,并使用 Postman 进行测试,那么让我们开始吧:))
首先,我们来看一下项目结构。
-/configurations
->/config.js
-package.json
-index.js
现在我们的项目已经完成,准备就绪,让我们来安装软件包吧。
打开项目目录下的命令行窗口,然后输入以下命令
npm install --save express body-parser morgan jsonwebtoken
那么,让我们来解释一下我们已经安装的软件包。
Express:著名的 Node.js 框架
body-parser:允许我们从请求体中获取数据
morgan:将请求记录到控制台。
jsonwebtoken:该软件包允许我们生成 jwt 并构建我们的中间件来检查令牌是否有效。
现在我们来看 config.js 文件。
config.js
实际上,这个文件用于设置一些大多数用户为了更好地组织项目而需要进行的配置。
他们可以设置数据库配置或其他用途的配置。在本例中,我们将使用此文件来设置创建 JWT 时要用到的密钥,因此该文件应如下所示。
module.exports = {
secret : "heymynameismohamedaymen"
}
现在让我们来看看 index.js 文件,这是我们应用程序中最重要的文件。
index.js
const express = require('express'),
bodyParser = require('body-parser'),
morgan = require('morgan'),
jwt = require('jsonwebtoken'),
config = require('./configurations/config'),
app = express();
//set secret
app.set('Secret', config.secret);
// use morgan to log requests to the console
app.use(morgan('dev'));
// parse application/x-www-form-urlencoded
app.use(bodyParser.urlencoded({ extended: true }));
// parse application/json
app.use(bodyParser.json());
app.listen(3000,()=>{
console.log('server is running on port 3000')
});
app.get('/', function(req, res) {
res.send('Hello world app is running on http://localhost:3000/');
});
要检查一切是否正常,请转到命令行并运行以下命令
node index.js
打开浏览器访问http://localhost:3000/
一切看起来都很好!
我们还可以看到,由于 Morgan 包的作用,该请求已记录在我们的控制台中。
设置身份验证系统
现在到了我们应用程序最精彩的部分:))。
在这个应用中,我们实际上不会使用存储在数据库中的真实模型,而是会设置一个静态的登录名和密码来检查用户是否存在,因为本文的重点是 JWT 的使用,所以您可以简单地修改我们即将编写的代码。
所以,让我们在 index.js 文件中创建身份验证路由。
这里我们选择 aymen 作为用户名,123 作为密码。
app.post('/authenticate',(req,res)=>{
if(req.body.username==="aymen"){
if(req.body.password===123){
//if eveything is okey let's create our token
const payload = {
check: true
};
var token = jwt.sign(payload, app.get('Secret'), {
expiresIn: 1440 // expires in 24 hours
});
res.json({
message: 'authentication done ',
token: token
});
}else{
res.json({message:"please check your password !"})
}
}else{
res.json({message:"user not found !"})
}
})
路由已经建立,我们可以获取令牌了……那么让我们用 Postman 做个测试吧。
现在我们有了令牌,作为客户端,我们首先需要以某种方式存储该令牌,有很多工具可以做到这一点,例如,如果我们使用浏览器,可以使用本地存储;如果我们使用 Android 创建移动应用程序,可以使用共享首选项。
设置中间件
目前我们已经有了令牌,可以向服务器发出 http 请求,但我们也必须构建中间件来处理每个 http 请求,搜索令牌并检查它是否有效。
但在创建中间件之前,我们必须先创建将受其保护的路由,因此在我们的 index.js 文件中,受保护的路由应该如下所示:
const ProtectedRoutes = express.Router();
app.use('/api', ProtectedRoutes);
现在,/api 下的每个路由都将受到中间件的保护,要访问使用 /api 作为父路由的资源,我们必须提供正确的令牌。
为了将令牌连同一些数据一起发送到服务器,我们通常将令牌存储在每个请求的标头中,之后中间件将处理 http 请求并从标头中提取令牌。
所以,让我们在 index.js 文件中编写实现该功能的代码。
ProtectedRoutes.use((req, res, next) =>{
// check header for the token
var token = req.headers['access-token'];
// decode token
if (token) {
// verifies secret and checks if the token is expired
jwt.verify(token, app.get('Secret'), (err, decoded) =>{
if (err) {
return res.json({ message: 'invalid token' });
} else {
// if everything is good, save to request for use in other routes
req.decoded = decoded;
next();
}
});
} else {
// if there is no token
res.send({
message: 'No token provided.'
});
}
});
为了检查我们的中间件是否有效,我们将创建另一个路由,在该路由中我们将返回一个产品数组,并将此路由设置为 /api,使用 ProtectedRoutes,之后我们将发出一个 GET 请求来获取数据。
首先,我们来创建路由
ProtectedRoutes.get('/getAllProducts',(req,res)=>{
let products = [
{
id: 1,
name:"cheese"
},
{
id: 2,
name:"carottes"
}
]
res.json(products)
})
现在我们尝试在不提供令牌的情况下获取产品列表,看看会发生什么。
这次中间件没有返回数据,因为我们没有提供令牌,或者换句话说,API 没有识别出我们,认为我们是想要窃取信息的坏人。
现在,我们将使用 Postman 将令牌添加到请求头中,然后再次发送请求。
现在一切看起来都很棒,我们已经收到数据了;))。
结论
在这个例子中,我们深入了解了 JWT 的用法及其对 Restful API 安全性的重要性。请注意,这并不是保障 Node.js 应用程序安全的唯一方法,但有很多工具可能非常有用。
我们希望通过这次展示,能够更好地理解令牌是如何创建的,路由是如何受到保护的,以及所有这些是如何在 Node.js 应用程序中管理的。
您可以通过以下链接找到该项目:
(https://github.com/medaymenTN/JWTNodeJS)
文章来源:https://dev.to/medaymentn/secure-your-node-js-api-with-json-web-token-5o5