【node.js】session认证机制、JWT认证机制进行鉴权

由于 用户进行访问 浏览器时,需要完成对用户身份的确认。称为身份验证,或者“鉴权”和“身份认证”。需要身份认证使用 session认证机制 或者 JWT 认证机制。

由于开发模式不同,身份认证也不同。

对于服务器渲染和前后端分离这两种开发模式来说,分别有不同的身份认证:

  • 服务端渲染:即前后端不分离,推荐使用 session 认证机制,有利于 SEO,不存在跨域。
  • 前后端分离:推荐使用 JWT 机制,在后台加载速度快。可以跨域

一、session 认证机制

由于 HTTP 协议 是无状态性(每次HTTP 请求都是独立的,多个HTTP请求没有直接关系,服务器不会主动保留每次HTTP请求的状态),所以解决这一无状态的限制,需要一个身份认证的方式进行存储识别,在Web开发的专业属于叫做 Cookie。session 认证机制 需要 配合 cookie 才能实现。

1. cookie

cookie 是 存储在 用户浏览器中不超过 4kb 的字符串。

是由键值对的方式,和其他用于控制 cookie 的有效期,安全性,使用范围的可选属性存在。

客户端第一次请求服务器时,服务器通过响应头的形式,会将未过期的cookie自动发送到客户端,自动存储在客户端,每次都请求携带cookie;客户端通过 请求头,自动将 cookie 发送给服务器,服务器就可以验证客户端的身份;再响应到客户端。
在这里插入图片描述

  • cookie 存储在 客户端,而且 客户端提供了 读写cookie 的API,因此就很容易被伪造。
    • 应用场景
      1. 保存用户上次登录的信息
      2. 用户的自动登录(或者记住密码)
      3. 上一次浏览的信息

2. Session 的工作原理

  • 由于 cookie 的安全性不高,所以使用 session 认证机制。
  • 将用户信息存储到 服务器的内存中,之后会生成对应的 cookie 字符串中,将生成的cookie相应到客户端。然后客户端再次发起请求,执行上面cookie相关的操作。
  • session 是在 cookie 的基础上进行。
2.1 express-session 实现 session 机制
  1. npm i express-session
  2. 配置 session 中间件
  3. 向 session 中 存储数据,通过 req.session 访问 和 使用 session 对象
  4. 从 session 中 获取数据,直接从 req.session 对象上 获取之前存储的数据
  5. 清空 session ,使用 req.session.destory() 函数,就可以清空服务器保存的 session 信息

二、JWT 认证机制

由于 session 认证机制 需要配合cookie才能实现,cookie 默认不支持跨域访问,所以,当涉及前端跨域请求后端接口的时候,需要做很多额外的配置,才能实现跨域 session 认证。

  • 当前端请求后端接口不存在 跨域问题的时候,推荐使用 session 身份认证机制
  • 当前端需要 跨域 请求后端接口的时候,不推荐使用 session 身份认证机制,推荐使用 JWT 认证机制。

1. 什么是 JWT

JWT 是目前 最流行的跨域认证解决方案。

JWT 有 三个部分,都代表各自的含义。

Header.Payload.Signature

//  其中 Header 头部,Payload 有效荷载,Signature 签名

Payload  部分才是真正的用户的信息,它是用户信息经过加密之后生成的字符串
Header、Signature  是安全性相关的部分,只是为了保证 token 的安全性

2. JWT 工作原理

在这里插入图片描述

2.1. express-jwt 实现 JWT 机制

客户端收到服务器返回的 JWT 之后,通常会将 token 值存储到
Local Storage 或者 Session Storage 中。
此后,客户端每次和服务器通信,都要带上 JWT。
推荐做法:

Authorization :Bearer <token>
  1. npm i jsonwebtoken express-jwt
  2. 导入 JWT 相关的包
    • const jwt = require(‘jsonwebtoken’)
    • const expressJWT = require(‘express-jwt’)
  3. 定义 secret 密钥
    • const secretKey = ‘itheima No1 _
  4. 在登陆成功后,生成 token 字符串
    • 调用 jsonwebtoken包提供的 sign() 方法,将用户信息加密成 JWT字符串。千万不要将密码加密到 token 字符中
    • jwt.sign({ username: userinfo.username }, secretKey, { expiresIn: ‘30s’ })
  5. 注册,将 JWT 字符串还原为 JSON 对象的中间件(解密)
    • app.use(expressJWT({ secret: secretKey }).unless({ path: [/^/api//] }))
    • 其中 unless 是除了某个页面不进行 生成token字符串
  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
以下是一个使用Node.js和express-jwt的完整Token处理和中间件的示例: 1. 安装必要的依赖 ``` npm install express express-jwt jsonwebtoken ``` 2. 创建一个JWT密钥 ``` const jwtSecret = 'mysecretkey'; ``` 3. 创建一个函数来生成令牌 ``` const jwt = require('jsonwebtoken'); function generateToken(user) { const payload = { sub: user.id, iat: Date.now() }; const options = { expiresIn: '1d' }; return jwt.sign(payload, jwtSecret, options); } ``` 4. 创建一个路由来登录并生成令牌 ``` const express = require('express'); const router = express.Router(); const User = require('../models/user'); router.post('/login', (req, res) => { const { email, password } = req.body; User.findOne({ email: email }, (err, user) => { if (err) { return res.status(500).json({ error: err }); } if (!user) { return res.status(401).json({ error: 'User not found' }); } if (!user.validPassword(password)) { return res.status(401).json({ error: 'Invalid password' }); } const token = generateToken(user); res.json({ token }); }); }); module.exports = router; ``` 5. 创建一个中间件来验证令牌 ``` const jwt = require('express-jwt'); function getTokenFromHeader(req) { if (req.headers.authorization && req.headers.authorization.split(' ')[0] === 'Bearer') { return req.headers.authorization.split(' ')[1]; } return null; } const auth = { required: jwt({ secret: jwtSecret, userProperty: 'payload', getToken: getTokenFromHeader }), optional: jwt({ secret: jwtSecret, userProperty: 'payload', getToken: getTokenFromHeader, credentialsRequired: false }) }; module.exports = auth; ``` 6. 使用验证令牌的中间件保护路由 ``` const express = require('express'); const router = express.Router(); const auth = require('../middleware/auth'); router.get('/protected', auth.required, (req, res) => { res.json({ message: 'You are authorized to access this protected route' }); }); router.get('/optional', auth.optional, (req, res) => { res.json({ message: 'This route can be accessed without a token' }); }); module.exports = router; ``` 现在,你可以使用这些路由来生成令牌、保护受保护的路由并允许可选的路由。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值