前言

前面选用了IdentityServer4做为认证授权的基础框架,感兴趣的可以看上篇<微服务下认证授权框架的探讨>,已经初步完成了authorization-code与implicit的简易demo(html+js 在IIS部署的站点),并实现了SSO,本想着将Demo迁移到vue工程是轻而易举,毕竟也没啥东西,最终拿到access_token,存储到store里,跟传统的jwt基本上一样,不出意外,意外总是会发生,不然也没办法水一篇帖子,玩笑归玩笑,如果有理解错误,或者使用不当的地方,欢迎拍砖,以免误人子弟

环境角色

  • vue2.0 cli
  • .net core 6.0

这里为什么不用vue3,尝试过,最终放弃了,本来就是半吊子的前端水平,vue3里的vite跟ts,极大的增加了学习成本,包升级后一些莫名其妙的bug,特别是vite,一些bug提示对我来说特别陌生与不友好(项目不报错,js控制台报错,好像是兼容之类的问题),总之还是太菜,解决不了,又菜又爱玩

准备动手

在IdentityServer4里,对于前端工程提供了oidc-client.js这个包,在github开源,不过在2021年左右就停止维护了,这里我收集了两条跟本次吐槽相关的Issues

https://github.com/IdentityModel/oidc-client-js/issues/1393

https://github.com/IdentityModel/oidc-client-js/issues/1360

OAuth2.0 与 OAuth2.1

吓了一跳,OAuth2.1是个什么玩意?来看看GPT的回答



原来官方还没有这个东西,市面上一些对OAuth2.0拓展或者增强的东西,搞了个OAuth2.1,或许只是一个草案,本次吐槽的坑点就是oidc-client.js里PKCE的使用,PKCE全称是 Proof Key for Code Exchange, 在2015年发布, 它是 OAuth 2.0 核心的一个扩展协议, 所以可以和现有的授权模式结合使用,比如 Authorization Code + PKCE,东西是好东西,但是强制使用,不与之前的OAuth2.0兼容,就要被骂了

啥是PKCE?

大白话,就是防止授权码(code)被坏人拦截,而设计的一个拓展协议,坏人拿到了code也换取不了access_token,它的实现过程也非常简单,三两句就能讲明白,就不画图了,直接上代码截图

三个角色,授权服务,前端工程,后端工程

  1. 认证中心登录,回调页面上多了两个参数

code_challenge_method 签名方法

code_challenge 签名

  1. 使用code换取access_token的时候,要多带一个code_verifier(随机生成的一个字符串) 参数,否则兑换失败

code_challenge = code_challenge_method(code_verifier)

  1. 协议约定,如果在认证中心生成code的时候,携带了code_challenge_method与code_challenge,那么在使用code兑换

    access_token的时候,必须携带code_verifier

如果这还听不明白,那我举个古代银票防伪的例子

张三去钱庄存银子的时候,跟钱庄做了约定,留下一句暗号(DNF)跟暗号的生成方式(取每个字的首字符)给钱庄,兑换者在用银票换银子的时候,钱庄会检查这张银票有没有跟张三做约定,如果有约定,则按照约定让兑换者提供明文,钱庄用兑换者提供的明文跟张三提供的暗号生成方式,来生成暗号,如果一致则允许兑换银子

银票 = code

暗号 = 签名(code_challenge )

暗号的生成方式 = 签名方法(code_challenge_method )

明文 = code_verifier(随机字符串)

为啥要喷oidc-client.js里PKCE的实现?

  1. PKCE关不了
var config = {
authority: "https://localhost:6201",
...
pkce:false
};

前面Issues有提过,提供了这个配置,但是不生效,总之一定会带上

  1. 回调逻辑存在问题
var userManager = new Oidc.UserManager(config);
userManager.signinRedirectCallback().then(function(user) {
// 登录成功,可以在这里处理登录后的逻辑,例如重定向到首页或显示欢迎信息
console.log('用户已登录:', user);
window.location.href = '/home'; // 重定向到应用的主页
}).catch(function(error) {
// 处理登录失败的情况
console.error('登录失败:', error);
alert('登录过程中发生错误,请重试。');
});





这是oidc-client.js里回调页面的处理,它自动做了处理,但是它绕过后端程序,直接向认证服务发起,这里返回400错误,是因为该客户端必须校验秘钥,我们一般将秘钥存储在后端程序,前端程序请求后端,后端带上客户端秘钥,将请求转发给认证服务,这才是authorization-code标准的认证流程,也相对安全

  1. 相同的版本,在(html+js)站点下,并没有启用PKCE,而在vue-cli工程,默认启用PKCE





这点也是我最郁闷的地方,最开始我怀疑是版本问题导致的,后面我降级到相同的版本,但是结果却还是一样,折腾了好久,依旧没有解决,*******

解决办法

  1. 后端强行关闭PKCE认证

既然vue-cli工程里发起的获取code,会携带PKCE认证信息,那我在重定向地址里,把这两个参数移除,那就搞定收工了

  1. 啃oidc-client.js源码,翻Issues,看看有没有转机

先看Issues,把问题关键字贴进去搜一下,很遗憾没有找到有用的东西,源码简单的翻了下,也没啥帮助

  1. 逆向oidc-client.js,重写回调页面逻辑

既然我们缺code_verifier,那就去找,打印config.userStore,就找到了,这得感谢作者没有每次都删除该对象,不然可能就真的芭比Q了,知道了位置,我们直接从Localstorage取,然后根据时间戳取最新的那条记录,然后提取出code_verifier

function getCodeVerifier() {
const allKeys = [];
const items =[];
for (let i = 0; i < localStorage.length; i++) {
allKeys.push(localStorage.key(i));
}
const pattern = /^oidc\./;
const oidcKeys = allKeys.filter(key => pattern.test(key));
for(let i =0;i< oidcKeys.length;i++){
const str = localStorage.getItem(oidcKeys[i]);
if(str != null && str != ''){
const model = JSON.parse(str);
if(model.created == '' || model.created == null || model.created == undefined){
continue
}
items.push(model)
localStorage.removeItem(oidcKeys[i])
}
}
const item = items.reduce((nearest, current) => {
return (nearest.created > current.created) ? nearest : current;
});
return item.code_verifier;
}

最终效果

oidc-client.js踩坑吐槽贴的更多相关文章

  1. react基础学习和react服务端渲染框架next.js踩坑

    说明 React作为Facebook 内部开发 Instagram 的项目中,是一个用来构建用户界面的优秀 JS 库,于 2013 年 5 月开源.作为前端的三大框架之一,React的应用可以说是非常 ...

  2. vue.js 踩坑第一步 利用vue-cli vue-router搭建一个带有底部导航栏移动前端项目

    vue.js学习 踩坑第一步 1.首先安装vue-cli脚手架 不多赘述,主要参考WiseWrong 的 Vue 爬坑之路(一)-- 使用 vue-cli 搭建项目 2.项目呈现效果 项目呈现网址:w ...

  3. Nuxt.js 踩坑记录,(1)引入fs包报错

    今天又是码农的一天. 但是写着写着,不知道为啥就页面就报错了, 如图所示,我在db/app.js下引入了fs这个模块,提示我npm install,我也照做了,但是仍然报错. 通过各种百度,踩坑,最终 ...

  4. Nuxt.js 踩坑记录(2) 使用sequelize时,提示install mysql2,安装了仍然不能解决问题

    打算写一个nuxt.js+sequelize+mysql的个人博客,遇到了挺多坑,还是坚持了下来,终于解决了这个bug. 今天不知道我做了什么,页面就报错了,定位到了使用sequelize的JS文件里 ...

  5. layui的引用js踩坑

    前言: 今天因为项目需要,需要使用layui,因为本身不多的前端经验,以为layui的用法和其他的前端框架,例如jquery,bootstrap等等,只需要直接引入layui.js,和layui.cs ...

  6. Nuxt.js 踩坑笔记 - 缓存向

    零.前言 最近参与了一个立足 seo 的移动端项目,公司前端工程主栈 vue,所以理所当然的用上了 nuxt,UI 主要选择了 Vant.   一.公共列表页的缓存 公共列表页由于数据量较大,故需要滚 ...

  7. nuxt.js踩坑之 - SSR 与 CSR 显示不一致问题

    [Vue warn]: The client-side rendered virtual DOM tree is not matching server-rendered content. This ...

  8. Nuxt.js 踩坑记录(3) Net.connection xxxx

    浏览器报的是Net.connection啥的错误 项目运行时报错这个 [HPM] Error occurred while trying to proxy request article from l ...

  9. JS踩过的坑

    一:DOM对象的查找 DOM的查找到的对象,除byID的之外,返回的都是一个数组,并不是DOM对象无法调用DOM对象的方法. 通过id查找: 因为id在一个HTML文件中唯一,因此查找到的只会是一个元 ...

  10. 微信小程序使用pako.js的踩坑笔记

    问题 今天组长跟我们讨论了个问题,说是文章存储占用有点大,消耗宽带流量费,让我看看能不能找个方法解决一下(文章存储的是html字符串).第一反应是没什么头绪,能想到的就是将相同的字符串替换成一个标识之 ...

随机推荐

  1. spring boot 配置文件占位符和多环境配置 [七]

    配置文件占位符 person.last-name=zhangsan person.age=${random.int} person.birth=2017/12/15 person.boss=false ...

  2. keystore 生成密钥

    前言 在安卓中,我们需要生存keystore来处理我们的证书: 我们很幸运在keystore中,在java中的bin下,已经有了keytool工具了,感谢java社区工作者. 正文 在命令窗口中使用k ...

  3. pageSpy - 远程调试利器

    视频版: https://www.bilibili.com/video/BV1Zi4y167TZ 前言 在工作中, 经常需要面对的问题就是处理客户提出的bug. 但是这个事儿最耗费精力甚至决定能不能修 ...

  4. hashchang事件是异步更新的

    1.代码 // 此时会触发hashchange location.hash = '/test' window.addEventListener('hashchange', () => { con ...

  5. 文件上传之Webshell连接方法

    "感谢您阅读本篇博客!如果您觉得本文对您有所帮助或启发,请不吝点赞和分享给更多的朋友.您的支持是我持续创作的动力,也欢迎留言交流,让我们一起探讨技术,共同成长!谢谢!" Websh ...

  6. TiDB Vector 抢先体验之用 TiDB 实现以图搜图

    本文首发自 TiDB 社区专栏:https://tidb.net/blog/0c5672b9 前言 最早知道 TiDB 要支持向量化的消息应该是在23年10月份左右,到第一次见到 TiDB Vecto ...

  7. 路由跳转报错:Uncaught (in promise) NavigationDuplicated {_name: "NavigationDuplicated", name: "NavigationDuplicated",...

    记录一个路由跳转的报错: 将换成

  8. uniapp+vue3聊天室|uni-app+vite4+uv-ui跨端仿微信app聊天语音/朋友圈

    原创研发uniapp+vue3+pinia2跨三端仿微信app聊天模板Uniapp-Wechat. uni-vue3-wchat基于uni-app+vue3+pinia2+uni-ui+uv-ui等技 ...

  9. 【爬虫案例】用Python爬取百度热搜榜数据!

    目录 一.爬取目标 二.编写爬虫代码 三.同步视频讲解 四.完整源码 一.爬取目标 您好,我是@马哥python说,一名10年程序猿. 本次爬取的目标是:百度热搜榜 分别爬取每条热搜的: 热搜标题.热 ...

  10. 【2023知乎爬虫】我用Python爬虫爬了2386条知乎评论!

    目录 一.爬取目标 二.展示爬取结果 三.爬虫代码讲解 3.1 分析知乎页面 3.2 爬虫代码 四.同步视频 五.完整源码 您好,我是 @马哥python说,一枚10年程序猿. 一.爬取目标 前些天我 ...