不同开发模式下的身份认证

不同开发模式下的身份认证:

服务器端渲染推荐使用Session认证机制

cookie是什么

cookie是存储在用户浏览器中的一段不超过4KB的字符串。他是有一个名称、一个值、和其他几个用于控制cookie有效期、安全性、使用范围的可选属性组成。

不同域名下的cookie各自独立,每当客户发起请求时,会自动把当前域名下所有未过期的cookie一同发送到服务器。

特性:自动发送、域名独立、过期时限、4KB限制

cookie在身份认证中的作用

客户端第一次请求服务器的时候,服务器通过响应头的形式,向客户端发送一个身份认证的cookie,客户端会自动将cookie保存在浏览器中。

随后,当客户端浏览器每次请求服务器的时候,浏览器会自动将身份认证相关的cookie,通过请求头的形式发送给服务器,服务器即可验明客户端的身份。

cookie不具有安全性

由于cookie是存储在浏览器中的,而且浏览器也提供了读写cookie的API,因此cookie很容易被伪造,不具有安全性。因此不建议服务器将重要的隐私数据,通过cookie的形式发送给浏览器。

提高身份认证的安全性

"会员卡+刷卡认证"的设计理念,就是session认证机制的精髓

Session

session工作原理

1、用户第一次登录浏览器客户端时填写账号密码登录,成功后将用户的基础信息存储在服务器的内存中,同时服务器生成对应的cookie字符串将cookie响应给浏览器客户端,浏览器自动把cookie存储在当下域名。

2、当用户再次发起请求想要登录页面时,就不用再次输入账号和密码,而是客户端浏览器通过请求头,自动把当前域名下所有可用cookie发送给服务器,服务器根据请求头中携带的cookie从内存中查找对应的用户信息,如果查找到对应的信息则认证成功,返回给用户登录后的页面。可以通过这种方式免去用户经常登录

使用 express-session中间件

1、安装后,通过app.use()来注册session中间件,示例代码:

--javascripttypescriptshellbashsqljsonhtmlcssccppjavarubypythongorustmarkdown

复制代码
var session = require('express-session')

app.use(session({
	secret:'keybord cat',//secret的值可以为任意字符串
	resave:false,//固定写法
	saveUninitialized:true//固定写法
}))

2、往session存数据

通过req.session来访问和使用对象,从而存储用户关键信息

--javascripttypescriptshellbashsqljsonhtmlcssccppjavarubypythongorustmarkdown

复制代码
apiRouter.post("/api/login", (req, res) => {
  req.session.user = req.body;//存储用户信息填到session
  req.session.islogin= true;//存储登陆状态填到session
  res.send({
    status: 0, //状态 成功0 失败1
    msg: "请求成功", //状态描述
  });
});

3、从session取数据

--javascripttypescriptshellbashsqljsonhtmlcssccppjavarubypythongorustmarkdown

复制代码
apiRouter.get("/api/username", (req, res) => {
	if(!req.session.islogin){
		return res.send({status:1,msg:'fail'})
	}
  req.session.user = req.body;//存储用户信息填到session
  req.session.islogin= true;//存储登陆状态填到session
  res.send({
    status: 0, //状态 成功0 失败1
    msg: "get请求成功", //状态描述
	username:req.session.user.username
  });
});

4、清空session

--javascripttypescriptshellbashsqljsonhtmlcssccppjavarubypythongorustmarkdown

复制代码
apiRouter.post("/api/logout", (req, res) => {
	req.session.destory()//清空
  res.send({
    status: 0, //状态 成功0 失败1
    msg: "退出登录成功", //状态描述
  });
});

前后端分离推荐使用JWT认证机制

Session局限性

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

注意:

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

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

什么是JWT

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

JWT工作原理

1、客户端浏览器登录时提交账号与密码,服务端验证通过后,将用户的信息对象经过加密之后生成token字符串,服务器将生成的token发送给客户端。

2、客户端将token存储到Localstorage或Sessionstorage,客户再次发起请求时,通过请求头的authorization字段将token发送给服务器。

3、服务器把token字符串还原成为用户的信息对象,用户身份认证成功后服务器针对当前用户生成特定响应内容。

组成部分

JWT通常由三部分组成,分别是Header头部、Payload有效荷载、signature签名。三者之间使用'.'分隔。

Payload部分才是真正的用户信息,它是用户信息经过加密之后生成的字符串。

Header、signature是安全性相关的部分只是为了保证token的安全性。

使用方式

客户端收到服务端返回的JWT之后,通常会将它存储在localstorage或sessionstorage中。

此后,客户端每次与服务器通信,都要带上这个GWT的字符串,从而进行身份认证。推荐的做法是把JWT放在HTTP的请求头authorization字段中,格式如下:

Authorization: Bearer <token>

Express中使用JWT

1、安装导入

npm install jsonwebtoken express-jwt

其中:jsonwebtoken用于生成JWT字符串,express-jwt用于将JWT字符串解析还原成JSON对象

--javascripttypescriptshellbashsqljsonhtmlcssccppjavarubypythongorustmarkdown

复制代码
const jwt = require('jsonwebtoken')
const expressjwt= require('express-jwt')

2、定义secret密钥

为了保证JWT字符串的安全性, 防止JWT字符串在网络传输过程中被别人破解, 我们需要专门定义一个用于加密和解密的secret密钥。

密钥的作用:

1.当生成JWT字符串的时候, 需要使用secret密钥对用户的信息进行加密, 最终得到加密好的JWT字符串。

2.当靶机WT字符串解析还原成JSON对象的时候需要使用secret密钥进行解密。

--javascripttypescriptshellbashsqljsonhtmlcssccppjavarubypythongorustmarkdown

复制代码
//定义一个scret,scret的本质是一个字符串
const secretKey = 'itheima No1 ^_^'

3、在登陆成功后生成jjwt字符串

调用jsonwebtoken包提供的sign()方法, 将用户的信息加密成JWT字符串响应给客户端:

--javascripttypescriptshellbashsqljsonhtmlcssccppjavarubypythongorustmarkdown

复制代码
//登录接口
app.post("/api/login", (req, res) => {
//。。。省略登陆失败的代码
  res.send({
    status: 200, 
    msg: "登录成功", //状态描述
	//调用JWT , sign()生成JWT字符串, 三个参数分别是:用户信息对象、加密密钥、配置对象
	token:jwt.sign({username:'zs',secretKey ,{expiresIn:'30s'}})//expiresIn:'30s'指时限30秒
  });
});

4、将jwt字符串还原为json对象

客户端每次在访问那些有权限的接口时,都需要主动通过请求头中的authorization字段,将token字符串发送到服务器进行身份认证。

此时,服务器可以通过express-jwt这个中间件,自动将客户端发送过来的token解析还原成JSON对象:

--javascripttypescriptshellbashsqljsonhtmlcssccppjavarubypythongorustmarkdown

复制代码
//使用app.use()来注册中间件
app.use(expressjwt({secret:secretKey}).unless({path:[/^\/api\//]}))
//expressjwt({secret:secretKey})就是用来解析token的中间件
//unless({path:[/^\/api\//]用来指定哪些接口不需要访问权限
//^\/api\/正则表达式,表示必须以/api开头,如:/api/xxxxx...

5、捕获解析JWT失败后产生的错误

使用express-jwt解析token字符串时,如果客户端发过来的token字符串过期或不合法,影响项目正常运行。我们可以通过express的错误中间件,捕获这个错误并进行相关处理,示例代码:

--javascripttypescriptshellbashsqljsonhtmlcssccppjavarubypythongorustmarkdown

复制代码
app.use(err,req,res,next) =>{
	//token解析失败导致的错误
	if(err.name === 'Unauthorization'){
		return res.send({status:401,message:'无效的token'})
	}
	//其他元婴导致的错误
	res.send({status:500,mesage:'未知错误'})
}
相关推荐
JarvanMo15 分钟前
2025 年真正有效的 App Store 优化(ASO)
前端·ios
{⌐■_■}17 分钟前
【JavaScript】前端两种路由模式,Hash路由,History 路由
前端·javascript·哈希算法
前端老鹰19 分钟前
HTML `<datalist>`:原生下拉搜索框,无需 JS 也能实现联想功能
前端·html
玲小珑21 分钟前
LangChain.js 完全开发手册(五)Runnable 接口与任务编排系统
前端·langchain·ai编程
江城开朗的豌豆38 分钟前
解密useEffect依赖数组
前端·javascript·react.js
江城开朗的豌豆1 小时前
React Hooks必杀技:前端工程师小杨带你玩转常用API!
前端·javascript·react.js
江城开朗的豌豆1 小时前
Redux状态更新:异步还是同步?
前端·javascript·react.js
前端小巷子1 小时前
Vue 项目性能优化实战
前端·vue.js·面试
Aphasia3111 小时前
useEffect 中Clean up 函数的执行机制
前端·react.js·面试
xw51 小时前
我的后台管理项目报Error: spawn …esbuild.exe ENOENT了
前端