在现代 Web 应用程序开发中,用户认证和授权是常见的需求。JWT(JSON Web Token)是一个使用 Node.js 等各种编程语言实现的开放标准,可以为 Web 应用程序实现安全的、可扩展的、无状态的用户认证和授权功能。
本篇文章将详细介绍使用 Node.js 和 JWT 所实现的用户认证和授权的完整流程,包括 JWT 原理、实现方法和最佳实践等。
JWT 简介
JSON Web Token(JWT)是一个开放的标准,定义了一种用于简洁、自包含的、安全地传输信息的方式。JWT 是在网络环境中传递声明的一种方式,主要用来在身份提供者和服务消费者之间传递认证信息。它可以被用来验证发送方声明的所有权或者声明的其他信息。
一个 JWT 由三部分组成:头部、载荷和签名。其中,头部和载荷都是 Base64 编码过的 JSON 对象,签名使用算法进行计算。JWT 可以以明文传输,但是建议使用 HTTPS 等安全通道传输。
头部中包含算法(默认为 HMAC SHA256)和 token 类型(默认为 JWT)等信息。载荷中包含需要传递的信息,比如用户 ID 和权限等。签名是由算法和头部、载荷中的数据计算得出的结果,主要用于验证数据的完整性和真实性。
在用户访问应用程序时,用户将会获得一个 JWT,之后在每个请求中都将该 JWT 发送给服务器。服务器将验证该 JWT 是否合法,然后允许用户访问相应资源。用户的 JWT 还可以在过期之前进行更新或者撤销。
使用 Node.js 和 JWT 实现用户认证和授权的完整流程
在本篇文章中,我们将使用 Express.js(Node.js 的常用框架)和 jsonwebtoken (JWT 的 Node.js 实现库)等工具来实现用户认证和授权的完整流程。
安装依赖
首先,我们需要通过以下命令安装必要的依赖:
npm install express jsonwebtoken body-parser bcryptjs dotenv
- Express.js:Web 应用程序框架
- jsonwebtoken:JWT 的 Node.js 实现库
- body-parser:解析请求体
- bcryptjs:密码加密和验证
- dotenv:从 .env 文件加载环境变量
创建配置文件
接下来,我们需要创建一个配置文件 .env
,用于存储应用程序的配置信息,如数据库连接地址、JWT 密钥和过期时间等。
# 应用程序配置 PORT=3000 # JWT 配置 JWT_SECRET=mysecretkey JWT_EXPIRES_IN=1h
创建数据库模型
我们使用 MongoDB 作为我们的数据库,并创建 user.js
模型。
-- -------------------- ---- ------- ----- -------- - -------------------- ----- ------ - -------------------- ----- ---------- - ----------------- ----- - ----- ------- --------- ---- -- ------ - ----- ------- --------- ----- ------- ---- -- --------- - ----- ------- --------- ---- -- ----- - ----- ------- ----- -------- --------- -------- ------ - --- ---------------------- ----- -------- ------ - -- ------------------------------ - ------- - ----- ---- - ----- ------------------- ------------- - ----- -------------------------- ------ --- -------------------------------- - ----- -------- ----------------- - ------ ----- ------------------------------- --------------- -- ----- ---- - ---------------------- ------------ -------------- - -----
这个模型中包含用户的名字、电子邮件、密码和角色等信息。我们使用 bcryptjs
库来加密用户的密码,并将 matchPassword
函数用于比较用户的密码是否正确。
创建用户控制器
我们在 controllers/user.js
中创建一个用户控制器,用于处理用户的注册、登录和获取用户信息等请求。
-- -------------------- ---- ------- ----- ------------ - --------------------------------- ----- ---- - -------------------------- ----- ------------- - ---------------------------------- -- ---- ------------------ - ------------------ ----- ---- -- - ----- - ----- ------ -------- - - --------- ----- ---------- - ----- -------------- ----- --- -- ------------ - ---------------- ----- --- --------------- - ----- ---- - ----- ------------- ----- ------ -------- --- -- ------ - ---------------------- ---- --------- ----- ---------- ------ ----------- ----- ---------- ------ ----------------------- --- - ---- - ---------------- ----- --- ---------------- - --- -- ---- ---------------- - ------------------ ----- ---- -- - ----- - ------ -------- - - --------- ----- ---- - ----- -------------- ----- --- -- ----- -- ------ ------------------------------ - ---------- ---- --------- ----- ---------- ------ ----------- ----- ---------- ------ ----------------------- --- - ---- - ---------------- ----- --- ---------------- - --- -- ------ --------------- - ------------------ ----- ---- -- - ----- ---- - ----- ---------------------------- -- ------ - ---------- ---- --------- ----- ---------- ------ ----------- ----- --------- --- - ---- - ---------------- ----- --- --------------- - ---
我们在控制器中包含了创建用户、用户登录和获取用户信息的函数。其中, createUser()
函数用于创建一个新的用户, authUser()
函数用于验证用户的登录, getUser()
函数则用于获取已登录用户的信息。
创建 JWT 生成函数
我们需要创建一个函数,用于生成 JWT 来验证用户的身份。
-- -------------------- ---- ------- ----- --- - ------------------------ ----- - ----------- -------------- - - ---------------------------- ----- ------------- - ---- -- - ------ ---------- -- -- ----------- - ---------- -------------- --- -- -------------- - --------------
这个函数中接受用户的 ID,使用 JWT 发行人和过期时间等信息生成一个 JWT,用于验证用户的身份。
创建身份验证中间件
我们在 middleware/authMiddleware.js
中创建一个身份验证中间件,用于验证用户是否已登录。
-- -------------------- ---- ------- ----- ------------ - --------------------------------- ----- --- - ------------------------ ----- ---- - -------------------------- ----- - ---------- - - ---------------------------- ----- ------- - ------------------ ----- ---- ----- -- - --- ------ -- - ------------------------- -- ---------------------------------------------- - - --- - ----- - --------------------------------- ------ ----- ------- - ----------------- ------------ -------- - ----- ---------------------------------------------- ------- - ----- ------- - --------------------- ---------------- ----- --- ------------------------ - - -- -------- - ---------------- ----- --- ------------------------ - --- -------------- - --------
如果请求头中包含 Bearer Token,我们使用 JWT 验证身份。验证成功后,我们将已登录用户的 ID 添加到请求中,以便在后续的请求中使用。
创建路由
我们在 routes/userRoutes.js
中创建一个路由,用于处理用户的请求。
-- -------------------- ---- ------- ----- ------- - ------------------- ----- - ----------- --------- ------- - - ------------------------------- ----- ------- - ---------------------------------------- ----- ------ - ----------------- ------------------------ ------------ --------------------- ---------- ---------------------- -------- --------- -------------- - -------
在路由中,我们使用控制器中定义的函数处理不同的请求。/register
和 /login
用于创建用户和用户登录, /profile
用于获取已登录用户的信息,需要先验证用户的身份。
创建应用程序
最后,我们创建一个 server.js
,用于创建我们的应用程序。
-- -------------------- ---- ------- ----- ------- - ------------------- ----- ------ - ------------------ ----- --------- - ----------------------- ----- ---------- - ------------------------------- ---------------- ----- --- - ---------- -- --- ------------------------ -- -- --------------------- ------------ -- ----- ------------ -- ---- ----- ---- - ---------------- -- ----- ---------------- -- -- - ------------------- ------- -- ----------------------- ---- -- ---- ---------- ---
我们在应用程序中使用中间件 express.json()
来解析请求体,并使用路由 userRoutes
处理不同的请求。
总结
在这篇文章中,我们通过详细的示例代码,介绍了使用 Node.js 和 JWT 实现用户认证和授权的完整流程。JWT 是一种轻量级的身份验证和授权方式,它可以实现无状态的 Web 应用程序设计,当应用程序需要水平扩展时(如部署在多个服务器中),使用 JWT 可以更加方便地实现灵活的身份验证和授权。在实现用户认证和授权时,我们需要注意保护用户信息的安全性,选择合适的加密算法和过期时间等。
来源:JavaScript中文网 ,转载请注明来源 https://www.javascriptcn.com/post/64ec6d93f6b2d6eab36b6d16