位置: IT常识 - 正文

【node进阶】深入浅出前后端身份验证(下)---JWT(node实战)

编辑:rootadmin
【node进阶】深入浅出前后端身份验证(下)---JWT

推荐整理分享【node进阶】深入浅出前后端身份验证(下)---JWT(node实战),希望有所帮助,仅作参考,欢迎阅读内容。

文章相关热门搜索词:node深入浅出pdf,node深入浅出pdf,nodejs深入浅出笔记,深入node.js技术栈,node深入浅出pdf,node 入门,nodejs进阶,深入node.js技术栈,内容如对您有帮助,希望把文章链接给更多的朋友!

✅ 作者简介:一名普通本科大三的学生,致力于提高前端开发能力 ✨ 个人主页:前端小白在前进的主页 🔥 系列专栏 : node.js学习专栏 ⭐️ 个人社区 : 个人交流社区 🍀 学习格言: ☀️ 打不倒你的会使你更强!☀️ 💯 刷题网站:这段时间有许多的小伙伴在问有没有什么好的刷题网站,博主在这里给大家推荐一款刷题网站:👉点击访问牛客网👈牛客网支持多种编程语言的学习,各大互联网大厂面试真题,从基础到拔高,快来体验一下吧!

🔥前言

上一篇文章中带领大家学习了session,session身份认证适应于服务端渲染,我们前后端分离项目中用的都是jwt,本篇文章会详细的介绍jwt!

📃目录JWT认证机制Session 认证的局限性什么是 JWTJWT 的工作原理JWT 的组成部分JWT 的三个部分各自代表的含义JWT 的使用方式Express 中使用 JWT安装 JWT 相关的包定义 secret 密钥在登录成功后生成 JWT 字符串将 JWT 字符串还原为 JSON 对象使用 req.auth 获取用户信息捕获解析 JWT 失败后产生的错误完整示例demo小结JWT认证机制Session 认证的局限性

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

同时Session存在一定的存储问题,例如:我们有一个集群,我们第一次选择在机器A中登录,第二次在机器B中登录,这样会导致我们的Session会复制来复制去的(如图所示)。

如果我们想解决这个问题,我们可以把Session挂载到一个单独的机器中去,但是这样的话又会导致一个问题:用户需要重新再登录一遍,这样的话就很烦(如图所示) 同时,Cookie存储的有效信息容易被CSRF(Cross-site request forgery)跨站请求伪造导致安全性的问题。

注意:

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

JWT(英文全称:JSON Web Token)是目前最流行的跨域认证解决方案。

JWT 的工作原理

注意: CSRF攻击的原因是浏览器会自动带上cookie,而不会带上token; 以CSRF攻击为例: cookie:用户点击了链接,cookie未失效,导致发起请求后后端以为是用户正常操作,于是进行扣款或者盗取网站操作; token:用户点击链接,由于浏览器不会自动带上token(因为我们把token保存到了localStorage或者sessionStorage中了),所以即使发了请求,后端的token验证不会通过,所以不会进行扣款或者盗取网站操作; 用户的信息通过 Token 字符串的形式,保存在客户端浏览器中。服务器通过还原 Token 字符串的形式来认证用户的身份

JWT 的组成部分

JWT 通常由三部分组成,分别是 Header(头部)、Payload(有效荷载)、Signature(签名)。 三者之间使用英文的“.”分隔,格式如下:

Header.Payload.Signature【node进阶】深入浅出前后端身份验证(下)---JWT(node实战)

JWT 字符串的示例:

eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VybmFtZSI6ImFkbWluIiwiaWF0IjoxNjY2NzA2NTE4LCJleHAiOjE2NjY3MDY1NDh9.Gtw5Hg0t83g11oZEoKPxi9UljxW02M3dse5mqT7iqlIJWT 的三个部分各自代表的含义

JWT 的三个组成部分,从前到后分别是 Header、Payload、Signature。 其中: Payload 部分才是真正的用户信息,它是用户信息经过加密之后生成的字符串。 Header 和 Signature 是安全性相关的部分,只是为了保证 Token 的安全性。

JWT 的使用方式

客户端收到服务器返回的 JWT 之后,通常会将它储存在 localStorage 或 sessionStorage 中。 此后,客户端每次与服务器通信,都要带上这个 JWT 的字符串,从而进行身份认证。推荐的做法是把 JWT 放在 HTTP 请求头的 Authorization 字段中,格式如下:

Authorization:Bearer tokenExpress 中使用 JWT安装 JWT 相关的包

运行如下命令,安装如下两个 JWT 相关的包:

npm i jsonwebtoken express-jwt

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

定义 secret 密钥

为了保证 JWT 字符串的安全性,防止 JWT 字符串在网络传输过程中被别人破解,我们需要专门定义一个用于加密和解密的 secret 密钥: 当生成 JWT 字符串的时候,需要使用 secret 密钥对用户的信息进行加密,最终得到加密好的 JWT 字符串 当把 JWT 字符串解析还原成 JSON 对象的时候,需要使用 secret 密钥进行解密

const jwt = require('jsonwebtoken')const expressJWT = require('express-jwt')// 密钥为任意字符串const secretKey = 'Bruce'在登录成功后生成 JWT 字符串

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

app.post('/api/login', (req, res) => { ... res.send({ status: 200, message: '登录成功', // jwt.sign() 生成 JWT 字符串 // 参数:用户信息对象、加密密钥、配置对象-token有效期 // 尽量不保存敏感信息,因此只有用户名,没有密码 token: jwt.sign({username: userInfo.username}, secretKey, {expiresIn: '10h'}) })})将 JWT 字符串还原为 JSON 对象

客户端访问有权限的接口时,需通过请求头的 Authorization 字段,将 Token 字符串发送到服务器进行身份认证 服务器可以通过 express-jwt 中间件将客户端发送过来的 Token 解析还原成 JSON 对象

// unless({ path: [/^\/api\//] }) 指定哪些接口无需访问权限app.use(expressJWT({ secret: secretKey }).unless({ path: [/^\/api\//] }))使用 req.auth 获取用户信息

当 express-jwt 中间件配置成功后,即可在那些有权限的接口中,使用 req.auth 对象,来访问从 JWT 字符串中解析出来的用户信息

// 这是一个有权限的 API 接口app.get('/admin/getinfo', function (req, res) { // TODO_05:使用 req.auth 获取用户信息,并使用 data 属性将用户信息发送给客户端 console.log(req.auth); res.send({ status: 200, message: '获取用户信息成功!', data: req.auth // 要发送给客户端的用户信息 })})捕获解析 JWT 失败后产生的错误

当使用 express-jwt 解析 Token 字符串时,如果客户端发送过来的 Token 字符串过期或不合法,会产生一个解析失败的错误,影响项目的正常运行 通过 Express 的错误中间件,捕获这个错误并进行相关的处理:

app.use((err, req, res, next) => { if (err.name === 'UnauthorizedError') { return res.send({ status: 401, message: 'Invalid token' }) } res.send({ status: 500, message: 'Unknown error' })})完整示例demo

app.js文件:

// 导入 express 模块const express = require('express')// 创建 express 的服务器实例const app = express()// TODO_01:安装并导入 JWT 相关的两个包,分别是 jsonwebtoken 和 express-jwtconst jwt = require('jsonwebtoken')const { expressjwt: expressJWT} = require('express-jwt')// 允许跨域资源共享const cors = require('cors')app.use(cors())// 解析 post 表单数据的中间件const bodyParser = require('body-parser')const { response } = require('express')app.use(bodyParser.urlencoded({ extended: false }))// TODO_02:定义 secret 密钥,建议将密钥命名为 secretKeyconst secretKey = 'lzqlmy ^_^!'// TODO_04:注册将 JWT 字符串解析还原成 JSON 对象的中间件app.use(expressJWT({secret : secretKey,algorithms:['HS256']}).unless({path:[/^\/api\//]}))// 登录接口app.post('/api/login', function (req, res) { // 将 req.body 请求体中的数据,转存为 userinfo 常量 const userinfo = req.body // 登录失败 if (userinfo.username !== 'admin' || userinfo.password !== '000000') { return res.send({ status: 400, message: '登录失败!' }) } // 登录成功 // TODO_03:在登录成功之后,调用 jwt.sign() 方法生成 JWT 字符串。并通过 token 属性发送给客户端 //1.参数一:用户的信息对象 参数二:加密的密钥 参数三:配置对象,可以配置当前 token 的有效期 //千万不要把密码加密到 token 字符串中 const tokenStr = jwt.sign({username:userinfo.username},secretKey,{expiresIn:'30s'}) res.send({ status: 200, message: '登录成功!', token: tokenStr // 要发送给客户端的 token 字符串 })})// 这是一个有权限的 API 接口app.get('/admin/getinfo', function (req, res) { // TODO_05:使用 req.user 获取用户信息,并使用 data 属性将用户信息发送给客户端 console.log(req.auth); res.send({ status: 200, message: '获取用户信息成功!', data: req.auth // 要发送给客户端的用户信息 })})// TODO_06:使用全局错误处理中间件,捕获解析 JWT 失败后产生的错误app.use((err,req,res,next)=>{ //这次错误是由token解析失败造成的 if(err.name === `UnauthorizedError`) { return res.send({ status : 401, message:'token已过期' }) } res.send({ status : 500, message : '未知的错误!' })})// 调用 app.listen 方法,指定端口号并启动web服务器app.listen(8888, function () { console.log('Express server running at http://127.0.0.1:8888')})

在postman中测试接口: 在登录接口中获取到token,得到token后进行复制 将token复制到获取信息的接口中来,在Headers中添加KEY值:Authorization,在VALUE中添加Bearer + token值。我们可以看到获取到了用户信息,当我们token过期的时候,错误中间件会提示token已过期

小结

在前后端分离的主流时代中,jwt是必须要学会的东西,可能在开发中你只需要承担前端的工作,但是你需要了解jwt的工作原理,以及能够处理好后端传过来的token,这种能力必须是要有的!继续加油吧,少年!

本文链接地址:https://www.jiuchutong.com/zhishi/300077.html 转载请保留说明!

上一篇:若依框架前端切换TagView时刷新问题(若依框架用到的技术)

下一篇:Java Web中的ServletContext对象(java web中的转发和重定向)

  • word画笔在哪(word画笔在哪wps)

    word画笔在哪(word画笔在哪wps)

  • 微博年度回忆怎么看(微博年度回忆怎么取消)

    微博年度回忆怎么看(微博年度回忆怎么取消)

  • 朋友圈怎么定位在其他地方(朋友圈怎么定位别的城市位置)

    朋友圈怎么定位在其他地方(朋友圈怎么定位别的城市位置)

  • 华为mate30多少赫兹刷新率(华为mate305g多少赫兹)

    华为mate30多少赫兹刷新率(华为mate305g多少赫兹)

  • 两个字符是几个空格(两个字符是几个空格键)

    两个字符是几个空格(两个字符是几个空格键)

  • 电脑锁屏按哪两个键(电脑锁屏按哪个按钮)

    电脑锁屏按哪两个键(电脑锁屏按哪个按钮)

  • 移动E000001怎么解决(移动e000004)

    移动E000001怎么解决(移动e000004)

  • 华为手机屏幕图片显示曝光(华为手机屏幕图标不见了怎么办)

    华为手机屏幕图片显示曝光(华为手机屏幕图标不见了怎么办)

  • 华为手机出现了盲人模式怎么办(华为手机出现了个圆圈如何删除)

    华为手机出现了盲人模式怎么办(华为手机出现了个圆圈如何删除)

  • 网络正常为什么微信发不出信息(网络正常为什么连接不到app store)

    网络正常为什么微信发不出信息(网络正常为什么连接不到app store)

  • 手机频繁黑屏是咋回事(手机频繁黑屏是什么原因华为)

    手机频繁黑屏是咋回事(手机频繁黑屏是什么原因华为)

  • 无线路由器上的reset是什么意思(无线路由器上的光信号闪红灯怎么办)

    无线路由器上的reset是什么意思(无线路由器上的光信号闪红灯怎么办)

  • 50赫兹和60赫兹的区别(50赫兹和60赫兹电流差别)

    50赫兹和60赫兹的区别(50赫兹和60赫兹电流差别)

  • 手机电台在哪里找到(手机的电台在哪)

    手机电台在哪里找到(手机的电台在哪)

  • 手机pages文件怎么打开(手机pages文稿怎么打开)

    手机pages文件怎么打开(手机pages文稿怎么打开)

  • 酷狗怎么开桌面歌词(酷狗怎么打开桌面)

    酷狗怎么开桌面歌词(酷狗怎么打开桌面)

  • b站怎么设置特别关注(b站怎么设置特别关注更新提醒)

    b站怎么设置特别关注(b站怎么设置特别关注更新提醒)

  • 微信电话为什么会自己挂掉(微信电话为什么老是异常关闭)

    微信电话为什么会自己挂掉(微信电话为什么老是异常关闭)

  • word尾注20后怎么加圆圈(2010word尾注)

    word尾注20后怎么加圆圈(2010word尾注)

  • 小米商城预约怎么取消(小米商城预约怎么看)

    小米商城预约怎么取消(小米商城预约怎么看)

  • 通过手机号怎么定位(通过手机号怎么查对方信息)

    通过手机号怎么定位(通过手机号怎么查对方信息)

  • iphonex个人热点如何开(iPhoneX个人热点打不开怎么办)

    iphonex个人热点如何开(iPhoneX个人热点打不开怎么办)

  • 手机回收站清空怎么恢复(手机回收站清空了怎么恢复照片)

    手机回收站清空怎么恢复(手机回收站清空了怎么恢复照片)

  • oppoa9怎么打开快充(oppoa9手机快捷功能在哪里设置)

    oppoa9怎么打开快充(oppoa9手机快捷功能在哪里设置)

  • 微信小程序web-view与H5之间交互(含支付)(微信小程序webview支付)

    微信小程序web-view与H5之间交互(含支付)(微信小程序webview支付)

  • 头歌-HTML基础(头歌HTML基础第一关初识HTML)

    头歌-HTML基础(头歌HTML基础第一关初识HTML)

  • 给织梦添加复制文档的功能(织梦网站怎么添加关键词)

    给织梦添加复制文档的功能(织梦网站怎么添加关键词)

  • 补做前几年税审对报税税务评级有什么影响?
  • 合伙企业缴纳的是什么税
  • 怎么找高新技术企业的数据
  • 合同金额含税不含税
  • 小微企业增值税起征点是多少
  • 企业所得税零申报表怎么填写
  • 开票要交印花税吗
  • 委托开发费用免所得税和增值税
  • 企业的哪些活动对企业有长期影响呢
  • 销售多余材料会计分录怎么做
  • 公司的旅游费怎么处理
  • 企业承担的法律责任有哪些保险
  • 签订代销合同的人有没有退货权
  • 企业收到宣传费怎么入账
  • 向公司一般户的银行借款怎么做账?
  • 发行股票时支付的发行费属于
  • 补发以前年度工资如何计税
  • 增值税一般纳税人认定标准
  • 赔偿金要交增值税吗
  • 抽奖获得的奖品有权转卖吗
  • 自己去税务局开票怎么开
  • 累计折旧是备抵类科目吗
  • 航天金税电子发票
  • 国内企业给国外企业开发票
  • 当月发工资当月报个税吗
  • reminder.exe - reminder是什么进程 有什么用
  • 公司收到保险公司赔款
  • 私营合伙企业个税怎么算
  • print-js
  • wordpress使用
  • 补充养老保险税前扣除标准与扣除比例
  • 事业单位长期应付款挂账处理规定
  • php处理数据
  • 结转销售成本的分录怎么写
  • 稽查补缴所得税分录
  • vue组件入门
  • phpcms邀请注册送积分
  • 土地增值税扣除率怎样计算
  • 固定资产报废如何记账
  • 税前扣除是什么时候
  • 个人退税证明怎么开具
  • 哪些无票费用能够抵扣所得税
  • 公司购买食品如何入账科目
  • 个人销售商品交什么税
  • 营改增后一般纳税人按简易办法计税的规定
  • 临时用工费开票项目
  • 法定盈余公积的主要用途
  • 先开票后出库会计处理
  • 房屋预售收入
  • 合理损耗如何处理
  • 差额事业单位的工资是由财政开支吗
  • 市场费用科目
  • 收到项目资本金怎么入账
  • 租车运货产生的费用
  • 收到上月已付款的材料
  • 违约金从货款中扣除如何记账
  • 库存商品发出计价测试
  • 小规模纳税人差额纳税申报表
  • 单位购入车辆能抵扣吗
  • 现汇账户和现钞账户
  • 在mysql中使用视图的限制不包括
  • 通过zeno实现加速屏幕显示操作教程
  • centos 安装chia
  • 苹果mac os x 10.7.5如何升级
  • windows任务管理器打不开
  • win10回收站文件在哪里
  • android canvas rotate
  • h5 nodejs
  • cocos2d开发的知名游戏
  • jquery左侧导航栏
  • js遍历获取指定数据
  • node的express干什么用
  • unity怎么添加ui界面图片
  • php守护进程的应用场景
  • Android多个surface
  • 公司完税证明去哪里打
  • 青岛税务局局长是什么级别?
  • 深圳国税税发票在哪里开
  • 国办函和国办发
  • 2021税务稽查重点方向
  • 免责声明:网站部分图片文字素材来源于网络,如有侵权,请及时告知,我们会第一时间删除,谢谢! 邮箱:opceo@qq.com

    鄂ICP备2023003026号

    网站地图: 企业信息 工商信息 财税知识 网络常识 编程技术

    友情链接: 武汉网站建设