身份认证相关内容

身份认证相关内容
LiSir1.身份认证的概念
- 身份认证又被称为鉴权,身份验证,是通过一定的手段,完成对用户身份的确认。
2.身份认证方案
对于服务端渲染和前后端分离这两种开发模式来说,分别有着不同的身份认证方案。
- 服务端渲染推荐使用 Session认证机制
- 前后端分离推荐使用 JWT认证机制
3.Session认证机制
1.了解HTTP协议的无状态性
- http协议的无状态性指的是客户端每次的HTTP请求都是独立的,连续多个请求之间没有直接的关系,服务器不会主动保留每次HTTP请求的状态
简单来说就是,服务器并不会记录你的状态,比如你登录过一次,那么下次再起发起请求时还需要再次登录。
在我们Web开发中,利用Cookie突破Http无状态协议
2.什么是Cookie
Cookie是存储在用户浏览器中一段不超过4KB的字符串。它由一个名称(name)、一个值(value)和其他几个用于控制Cookie有效期、安全性、使用范围的可选属性组成。
不同域名下的Cookie各自独立,每当客户端发起请求时,会自动把当前域名下所有未过期的Cookie一同发送到服务器。
Cookie的特性:1.自动发送 2.域名独立 3.过期时限 4.4KB限制
3.Cookie在身份认证中的作用
客户端第一次请求服务器的时候,服务器通过响应头的形式,向客户端发送一个身份认证的 Cookie,客户端会自动将 Cookie 保存在浏览器中。
随后,当客户端浏览器每次请求服务器的时候,浏览器会自动将身份认证相关的Cookie,通过请求头的形式发送给服务器,服务器即可验明客户端的身份
4.Cookie不具有安全性
由于Cookie是存储在浏览器中,而且浏览器也提供了读写Cookie的API,因此Cookie很容易被伪造,不具有安全性。
5.提高身份认证的安全性
方法:客户端出示的Cookie后,在服务器端进行Cookie验证,通过了,才可以。这也是Session认证机制的精髓。
6.Session的工作原理
一图来了解工作原理
4.在Express中使用Session认证
1.安装
1 | npm i express-session |
2.配置
1 | //导入安装的session模块 |
- secret:
secret属性是一个必需的选项,用于签名session cookie。这个字符串应该是一个复杂的、随机的、且对于外部不可预测的值,以保证session数据的安全性。它作为加密cookie的密钥。您设置的'anything all can'仅作为一个示例,实际部署时应使用更安全的随机字符串。 - resave: 设置为
false意味着只有当session数据发生改变时,才会保存到session store中。如果设置为true,即使session数据没有变化,每次请求也会尝试保存session。设置为false可以减少不必要的I/O操作。 - saveUninitialized: 当设置为
true时,即使session数据没有被修改,也会在每个响应结束前保存未初始化的session。一个未初始化的session是指客户端新建立连接但尚未存储任何数据的session。这个选项通常在开发阶段开启,以确保新用户总是能获得一个session,但在生产环境中可能需要根据实际情况调整,因为它可能导致无用session的累积。
3.向session中存储数据
1 | //导入安装的session模块 |
通过白框中的代码,将用户信息存入session中,req.session这个对象是在导入了express-session模块后才有的,.user是们自定义的一个属性。
4.从Session中取数据
可以从req.session对象上获取之前存储的数据
1 | //获取用户账号接口 |
5.清空session
调用**req.session.destory()**函数即可
情景模拟:当用户退出登录时,清空session
1 | //退出接口 |
5.JWT认证机制
- JWT适用于跨域认证
- JWT全称为JSON Web Token。
1.JWT工作原理
- 核心:用户信息通过Token字符串的形式,保存在客户端浏览器中,服务器通过还原Token字符串的形式来认证用户的身份。
而Session是把客户信息存储在了服务器端
2.JWT的组成部分
- JWT通常有三部分组成,分别是Header(头部)、Payload(有效载荷)、Signature(签名)
- 三者之间通过
.分割
字符串示例:
其中:
- Payload部分是用户信息,加密之后生成的
- Header和Signature是安全性相关部分,保证Token的安全性
3.JWT的使用方式
客户端收到服务器返回的 JWT 之后,通常会将它储存在 localStorage 或 sessionStorage 中。
此后,客户端每次与服务器通信,都要带上这个JWT的字符串,从而进行身份认证。推荐的做法是把JWT 放在 HTTP请求头的 Authorization 字段中,
格式如下:
1 | Authorization: Bearer <token> |
6.在Express中使用JWT
1.安装
安装两个包,分别是:jsonwebtoken和express-jwt
1 | npm i jsonwebtoken express-jwt |
- jsonwebtoken用于生成JWT字符串
- express-jwt用于将JWT字符串解析还原
1 | const express = require('express') |
2.定义secret密钥
为了保证JWT字符串的安全性,防止JWT字符串在网络传输过程中被别人破解,我们需要专门定义一个用于加密和解密的密钥:
- 当生成JWT字符串的时候,需要使用密钥对用户的信息进行加密,最终得到加密好的jt字符串
- 当把JWT字符串解析还原成JSON对象的时候,需要使用密钥进行解密
1 | //定义密钥 |
3.生成Token字符串
在登录成功之后,调用 jwt.sign() 方法生成 JWT 字符串。并通过 token 属性发送给客户端
该方法接收三个参数:
- 参数1:用户的信息对象、
- 参数2:加密的秘钥
- 参数3:配置对象,可以配置当前 token 的有效期
下面是示例
1 | // 登录接口 |
4.将JWT字符串还原为JSON对象
1 | app.use(expressJWT({ secret: secretKey }).unless({ path: [/^\/api\//] })) |
通过.unless方法可以指定不需要权限的接口,在访问有权限的接口时,需要携带tonken进行鉴权认证。通过才能够访问,而token就是我们自主操作加密生成的。
5.使用req.user获取用户信息
注意:只要配置成功了 express-jwt 这个中间件,就可以把解析出来的用户信息,挂载到 req.user 属性上
user属性上包含哪些信息,是我们在进行加密时决定的。
1 | const tokenStr = jwt.sign({ username: userinfo.username }, secretKey, { expiresIn: '30s' }) |
在上面这条加密代码中,我们把用户的username进行加密,那么在访问时,就只能获取username不会获取其他信息。expiresIn: '30s'指该token有效期时30s
6.JWT解析失败捕获错误
使用全局错误处理中间件,捕获解析 JWT 失败后产生的错误
1 | app.use((err,req,res,next)=>{ |
该案例完整代码
1 | // 导入 express 模块 |








