In modern web
applications, user authentication is a very important and indispensable part. The use Node.js
and Express
framework can easily implement user identity authentication. In the process, jsonwebtoken
this JWT
protocol-based module can help us implement a safe and reliable authentication mechanism, allowing us to easily generate, parse and verify JWT
. This article mainly introduces how to use modules in the framework Node.js
to implement user authentication.Express
jsonwebtoken
1. What is jwt
jwt introduction : https://restfulapi.cn/jwt
JWT
( JSON Web Token
) is an JSON
open standard based on , for transmitting claims over the web in a secure manner . JWT
Typically used for authentication and authorization . It is a self-contained authentication mechanism consisting ofthree parts: header, payload and signature . JWT
The header and payload are encoded Base64
strings JSON
, and the signature is a string calculated by hashing the header and payload using a key. JWT
It can be transmitted between the client and the server, and the data can be protected from tampering during transmission. Since it is stateless, it simplifies Web
application development and maintenance.
2. Basic use of jsonwebtoken
jsonwebtoken
is a Node.js
library for creating, decoding and validating JWT
tokens ( JSON Web Tokens
). In Web
applications, these tokens are typically used for authentication and authorization .
Here are the basic steps how to use Node.js
in the app .jsonwebtoken
1. Install jsonwebtoken
First, you need to add the jsonwebtoken package to your project using npm or yarn:
npm install jsonwebtoken --save
or
yarn add jsonwebtoken
2. Import and use
Then, import jsonwebtoken in your code:
const jwt = require('jsonwebtoken');
3. Create a token
Create a token:
let token = jwt.sign({
foo: 'bar' }, 'shhhhh');
In the above code, we jwt.sign
created a new token using method.
This method requirestwo parameters:
- An object containing your
payload
(the data in this object will be encoded into the generated token) such as:userInfo
, - The secret string used to sign tokens .
4. Verify the token
Verify a token:
jwt.verify(token, 'shhhhh', (err, decoded) => {
if (err) {
// 处理错误
} else {
// 使用解码后的令牌数据
}
});
Use jwt.verify
methods to decode and verify a token.
The method requiresthree parameters:
- decoded token ,
- the same secret string used for signing ,
- Callback function to be called when the operation completes .
Notice:
-
All tokens should be
HTTPS
sent via-only to prevent interception. -
The secret string should remain private within your application and not be known by others.
-
Any information stored in the token can be decoded by anyone with the secret. Therefore, you should never store sensitive information (such as passwords or bank account information) in tokens .
3. Application example in express
In actual projects, we can use jsonwebtoken
modules to implement identity authentication. jsonwebtoken
Is JSON Web Tokens(JWT)
a protocol-based implementation module that can be used for generation, parsing, and verification JWT
. JWT
is an JSON
open standard based on (RFC 7519)
, for the secure transmission of claims over the web.
Here is an example of using express
and jsonwebtoken
implementing authentication:
const express = require('express');
const jwt = require('jsonwebtoken');
const app = express();
// 定义一个中间件函数,用于身份认证
function verifyToken(req, res, next) {
// 从请求头中获取token
const token = req.headers['authorization'];
if (!token) {
return res.status(401).send({
auth: false,
message: 'No token provided.'
});
}
// 验证token是否有效
jwt.verify(token, process.env.SECRET_KEY, (err, decoded) => {
if (err) {
return res.status(500).send({
auth: false,
message: 'Failed to authenticate token.'
});
}
// 将解码的用户信息存储到请求对象中
req.userId = decoded.id;
next();
});
}
// 定义一个路由,需要身份认证
app.get('/api/protected', verifyToken, (req, res, next) => {
// 返回受保护的数据
res.status(200).send({
message: 'Access granted.'
});
});
// 定义一个路由,用于登录,返回token
app.post('/api/login', (req, res, next) => {
// 从数据库中获取用户信息
const user = {
id: 123 };
// 生成token
const token = jwt.sign({
id: user.id }, process.env.SECRET_KEY, {
expiresIn: 60 * 60 // token有效期为1小时
});
// 返回token
res.status(200).send({
auth: true,
token: token
});
});
// 启动服务器,监听端口
app.listen(3000, () => {
console.log('Server started on port 3000');
});
In the above example, we defined a middleware function verifyToken
for authentication. This function is obtained from the request header token
and jsonwebtoken的verify
validated by the method token
. If the verification is passed, the user information will be stored in the request object for subsequent routing functions to use.
We also define two routing functions, /api/protected
and /api/login
. /api/protected
Authentication is required to access, and /api/login
it is used for login, and the generated one is returned token
.
In actual projects, we should SECRET_KEY
put such sensitive information as environment variables to improve security. In addition, we can also use jsonwebtoken
other functions provided, such as verified token
signature algorithm, payload
and header
other information.
Four, jwt logic extraction
In the above example, we use jwt to implement identity authentication, but this is only authenticated in one interface. If there are more interfaces, do we have to add this authentication middleware every time? In this way, not to mention whether the development and implementation are tiring or redundant, it is also very unreasonable from the perspective of maintenance. Therefore, we should extract the authentication logic to facilitate interface calling and maintenance. Specific steps are as follows:
1. Create a new jwt.js file
This file encapsulates three functions
- token generation
- token authentication
- Exclude which interfaces can be accessed without authentication, for example
/login
,
// jwt.js
const jwt = require("jsonwebtoken");
const {
promisify } = require("util");
const {
uuid } = require("../config/config.default");
const tojwt = promisify(jwt.sign);
const verfiy = promisify(jwt.verify);
// 生成token
module.exports.createToken = async (userinfo) => {
var token = await tojwt({
userinfo }, uuid, {
expiresIn: 60 * 60 * 24,
});
return token;
};
// jwt认证的中间件
const jwtAuthMiddleware = async (req, res, next) => {
var token = req.headers.authorization;
token = token ? token.split("Bearer ")[1] : null;
if (!token) {
return res.status(402).json({
error: "请传入token" });
}
if (token) {
try {
let userinfo = await verfiy(token, uuid);
req.user = userinfo;
next();
} catch (error) {
res.status("402").json({
error: "无效的token" });
}
} else {
next();
}
};
// 承认的url排除列表
const jwtAuthExcluedList = ['/api/login', '/api/register'];
// 检查排除列表的中间件
module.exports.jwtAuthExclued = (req, res, next) => {
// 检查请求 URL 是否在排除 jwtAuth 的列表里面
if (jwtAuthExcluedList.includes(req.path)){
next(); // 在列表里,跳过后续中间件
} else {
jwtAuthMiddleware(req, res, next); // 不在列表里,就调用jwt中间件进行身份认证
}
};
After encapsulating in this way, we only need to add the middleware used to realize the authentication jwtAuthExclued
of the interface before accessing the route, and call the generation in the interface .token
login
createToken
token
2. Generate token in the login interface
for example:
- loginController
// login
// 用户登录
exports.login = async (req, res) => {
// 客户端数据验证
// 链接数据库查询
var dbBack = await User.findOne(req.body)
if (!dbBack) {
return res.status(402).json({
error: "邮箱或者密码不正确" })
}
dbBack = dbBack.toJSON()
dbBack.token = await createToken(dbBack)
res.status(200).json(dbBack)
}
3. Add global authentication middleware
- app.js
const express = require("express");
const app = express();
const {
jwtAuthExclued } = require("./util/jwt");
const router = require("./router");
// 添加排除jwt中间件
app.use(jwtAuthExclued);
// 添加路由中间件
app.use('/api', router);
Five, jwt and session comparison
Here is a comparison table JWT
with Session
:
Contrast factor | JWT | Session |
---|---|---|
storage | Stored on the client side, does not require the server to maintain session state. | Stored on the server, the server needs to maintain session information. |
safety | The encryption is stricter, but if the token is stolen, the attacker can use it arbitrarily. | If the sessionID is stolen, an attacker can log in as a user. |
performance | The token needs to be verified and decoded every time a request is made, and the performance is poor. | Just look up the sessionID to get the session information, and the performance is better. |
Scalability | It is easier to expand in a multi-server or cross-domain environment. | In a multi-server environment, sessions need to be synchronized, and the scalability is poor. |
data size | JWT is larger in size than sessionID and thus requires more bandwidth. | The size of sessionID is stable and requires less bandwidth. |
Expire date | Different expiration times can be set for each token. | All sessions usually have the same expiration time. |
client storage location | Can be stored in Cookie, LocalStorage, SessionStorage | Stored in cookies. |
cross-domain issues | No cross-domain issues, and friendly to mobile applications. | Cross-domain issues are complex and require the server to support CORS. |
state | Stateless, the server does not need to save user information. | Stateful, the server needs to save user information. |
scenes to be used | Used for authentication and information exchange, especially suitable for single-page applications (SPA) and projects with front-end and back-end separation | Mainly used to record user status and adapt to traditional back-end rendering Web services |
Generally speaking, it JWT
is suitable for API
services with front-end and back-end separation. It can simplify the storage requirements of the server, provide better cross-platform compatibility and scalability, and also provide a safe and reliable identity authentication mechanism . It Session
is suitable for server-rendered web applications, which can provide higher security and callability, and can also reduce the traffic burden on the client . Different scenarios need to choose the most suitable identity authentication scheme, and choose according to actual needs.
6. Summary
In this article, we explored how to implement authentication in the framework Node.js
of . We start by introducing the basics of protocols and modules, then show how to use them in to generate, parse, and validate . Through an example in an actual project, we demonstrate how to use it in combination with routing middleware to implement a user authentication mechanism based on . Using it can provide a more secure and reliable user authentication scheme for our web applications, and the advantages are also obvious: there is no need to save information on the server side, and it has the characteristics of scalability and cross-platform compatibility. Through the introduction of this article, I believe that readers have been able to master the basic usage methods and principles, and can use it in actual projects to implement a safe and reliable identity authentication mechanism.Express
jsonwebtoken
JWT
jsonwebtoken
Express
jsonwebtoken
JWT
jsonwebtoken
token
jsonwebtoken
jwt
session
jsonwebtoken
jsonwebtoken