使用 IdentityServer 保护 Vue 前端 - 行业资讯 -

当前位置:首页  >  行业资讯  > 正文

使用 IdentityServer 保护 Vue 前端

使用 IdentityServer 保护 Vue 前端
2022-12-20 16:11:28
前情提要

《使用 IdentityServer 保护 Web 应用(AntD Pro 前端 + SpringBoot 后端)》中记录了使用 IdentityServer 保护前后端的过程,其中的前端工程是以 UMI Js 为例。今天,再来记录一下使用 IdentityServer 保护 Vue 前端的过程,和 UMI Js 项目使用 umi plugin 的方式不同,本文没有使用 Vue 相关的插件,而是直接使用了 oidc-client js。

另外,我对 Vue 这个框架非常不熟,在 vue-router 这里稍微卡住了一段时间,后来瞎试居然又成功了。针对这个问题,我还去 StackOverflow 上问了,但并没有收到有效的回复:https://stackoverflow.com/questions/74769607/how-to-access-vues-methods-from-navigation-guard


【资料图】

准备工作

首先,需要在 IdentityServer 服务器端注册该 Vue 前端应用,仍然以代码写死这个客户端为例:

new Client{ClientId = "vue-client",ClientSecrets = { new Secret("vue-client".Sha256()) },ClientName = "vue client",AllowedGrantTypes = GrantTypes.Implicit,AllowAccessTokensViaBrowser = true,RequireClientSecret = false,RequirePkce = true,RedirectUris ={"http://localhost:8080/callback","http://localhost:8080/static/silent-renew.html",},AllowedCorsOrigins = { "http://localhost:8080" },AllowedScopes = { "openid", "profile", "email" },AllowOfflineAccess = true,AccessTokenLifetime = 90,AbsoluteRefreshTokenLifetime = 0,RefreshTokenUsage = TokenUsage.OneTimeOnly,RefreshTokenExpiration = TokenExpiration.Sliding,UpdateAccessTokenClaimsOnRefresh = true,RequireConsent = false,};

在 Vue 工程里安装 oidc-client

yarn add oidc-client

在 Vue 里配置 IdentityServer 服务器信息

在项目里添加一个 src/security/security.js文件:

import Oidc from "oidc-client"function getIdPUrl() {return "https://id6.azurewebsites.net";}Oidc.Log.logger = console;Oidc.Log.level = Oidc.Log.DEBUG;const mgr = new Oidc.UserManager({authority: getIdPUrl(),client_id: "vue-client",redirect_uri: window.location.origin + "/callback",response_type: "id_token token",scope: "openid profile email",post_logout_redirect_uri: window.location.origin + "/logout",userStore: new Oidc.WebStorageStateStore({store: window.localStorage}),automaticSilentRenew: true,silent_redirect_uri: window.location.origin + "/silent-renew.html",accessTokenExpiringNotificationTime: 10,})export default mgr

在 main.js 里注入登录相关的数据和方法数据

不借助任何状态管理包,直接将相关的数据添加到 Vue 的 app 对象上:

import mgr from "@/security/security";const globalData = {isAuthenticated: false,user: "",mgr: mgr}

方法

const globalMethods = {async authenticate(returnPath) {console.log("authenticate")const user = await this.$root.getUser();if (user) {this.isAuthenticated = true;this.user = user} else {await this.$root.signIn(returnPath)}},async getUser() {try {return await this.mgr.getUser();} catch (err) {console.error(err);}},signIn(returnPath) {returnPath ? this.mgr.signinRedirect({state: returnPath}) : this.mgr.signinRedirect();}}

修改 Vue 的实例化代码

new Vue({router,data: globalData,methods: globalMethods,render: h => h(App),}).$mount("#app")

修改 router

在 src/router/index.js中,给需要登录的路由添加 meta 字段:

Vue.use(VueRouter)const router = new VueRouter({{path: "/private",name: "private page",component: resolve => require(["@/pages/private.vue"], resolve),meta: {requiresAuth: true}}});export default router

接着,正如在配置中体现出来的,需要一个回调页面来接收登录后的授权信息,这可以通过添加一个 src/views/CallbackPage.vue文件来实现:

<script>export default {async created() {try {const result = await this.$root.mgr.signinRedirectCallback();const returnUrl = result.state ?? "/";await this.$router.push({path: returnUrl})}catch(e){await this.$router.push({name: "Unauthorized"})}}}</script>

然后,需要在路由里配置好这个回调页面:

import CallbackPage from "@/views/CallbackPage.vue";Vue.use(VueRouter)const router = new VueRouter({routes: {path: "/private",name: "private page",component: resolve => require(["@/pages/private.vue"], resolve),meta: {requiresAuth: true}},{path: "/callback",name: "callback",component: CallbackPage}});export default router

同时,在这个 router 里添加一个所谓的“全局前置守卫”(https://router.vuejs.org/zh/guide/advanced/navigation-guards.html#%E5%85%A8%E5%B1%80%E5%89%8D%E7%BD%AE%E5%AE%88%E5%8D%AB),注意就是这里,我碰到了问题,并且在 StackOverflow 上提了这个问题。在需要调用前面定义的认证方法时,不能使用 router.app.authenticate,而要使用 router.apps[1].authenticate,这是我通过 inspect router发现的:

...router.beforeEach(async function (to, from, next) {let app = router.app.$data || {isAuthenticated: false}if(app.isAuthenticated) {next()} else if (to.matched.some(record => record.meta.requiresAuth)) {router.apps[1].authenticate(to.path).then(()=>{next()})}else {next()}})export default router

到了这一步,应用就可以跑起来了,在访问 /private 时,浏览器会跳转到 IdentityServer 服务器的登录页面,在登录完成后再跳转回来。

添加 silent-renew.html

注意 security.js,我们启用了 automaticSilentRenew,并且配置了 silent_redirect_uri的路径为 silent-renew.html。它是一个独立的引用了 oidc-client js 的 html 文件,不依赖 Vue,这样方便移植到任何前端项目。

oidc-client.min.js

首先,将我们安装好的 oidc-client 包下的 node_modules/oidc-client/dist/oidc-client.min.js文件,复制粘贴到 public/static目录下。

然后,在这个目录下添加 public/static/silent-renew.html文件。

Silent Renew Token<script src="oidc-client.min.js"></script><script>console.log("renewing tokens");new Oidc.UserManager({userStore: new Oidc.WebStorageStateStore({ store: window.localStorage })}).signinSilentCallback();</script>

给 API 请求添加认证头

最后,给 API 请求添加上认证头。前提是,后端接口也使用同样的 IdentityServer 来保护(如果是 SpringBoot 项目,可以参考《[使用 IdentityServer 保护 Web 应用(AntD Pro 前端 + SpringBoot 后端) - Jeff Tian的文章 - 知乎](https://zhuanlan.zhihu.com/p/533197284) 》);否则,如果 API 是公开的,就不需要这一步了。

对于使用 axios 的 API 客户端,可以利用其 request interceptors,来统一添加这个认证头,比如:

import router from "../router"import Vue from "vue";const v = new Vue({router})const service = axios.create({// 公共接口--这里注意后面会讲baseURL: process.env.BASE_API,// 超时时间 单位是ms,这里设置了3s的超时时间timeout: 20 * 1000});service.interceptors.request.use(config => {const user = v.$root.user;if(user) {const authToken = user.access_token;if(authToken){config.headers.Authorization = `Bearer ${authToken}`;}}return config;}, Promise.reject)export default service

标签:

(责任编辑:news01)
95后姑娘坚持画云千余天 网友:温柔笔触里有浪漫诗意

95后姑娘坚持画云千余天 网友:温柔笔触里有浪漫诗意

  95后湖北姑娘坚持画云千余天   千万网友称赞:她温柔的笔触里有种浪漫的诗意  你喜欢看云吗?...
10-12 14:06:16
保险公司频遭“内鬼”撬单骗津贴 背后犯罪团伙落网

保险公司频遭“内鬼”撬单骗津贴 背后犯罪团伙落网

保险公司频遭“内鬼”撬单骗津贴,办案人员经深入调查牵出背后的犯罪团伙——  揭秘“保险黑产团伙”...
10-12 14:06:16
黑龙江省高风险地区清零

黑龙江省高风险地区清零

  中新网哈尔滨10月12日电 (程岩 记者 史轶夫)黑龙江省卫健委12日发布消息,11日0-24时,黑龙江省...
10-12 14:06:16
绑架案牵出医疗腐败窝案 彰显有线索一查到底反腐决心

绑架案牵出医疗腐败窝案 彰显有线索一查到底反腐决心

  绑架案牵出医疗腐败窝案的沉重警示  近日,广西来宾市纪委监委印发《来宾市以案促改警示教育读本...
10-12 14:06:15
河北平山一通勤班车发生涉水倾覆事故 公安部工作组赴现场指导工作

河北平山一通勤班车发生涉水倾覆事故 公安部工作组赴现场指导工作

  法治日报全媒体记者 董凡超  10月11日7时许,河北省石家庄市平山县钢城路滹沱河大桥施工辅路发生...
10-12 14:06:15
今天北京延续秋高气爽 明天夜间或有小雨上线

今天北京延续秋高气爽 明天夜间或有小雨上线

  中国天气网讯 今天(10月12日),北京将延续秋高气爽的天气,但白天最高气温仍在19℃,夜间最低气温8...
10-12 14:06:15
台风“圆规”将影响东南沿海 北方局地有一次弱降水过程

台风“圆规”将影响东南沿海 北方局地有一次弱降水过程

  中新网10月12日电 据中央气象台网站消息,昨日08时至今日06时,浙江东北部、广东雷州半岛、海南岛...
10-12 14:06:15
受台风“圆规”影响 琼州海峡再次停航

受台风“圆规”影响 琼州海峡再次停航

  南方日报讯 (记者 黄叙浩 实习生 徐贝贝 通讯员 粤应宣)记者从省应急管理厅获悉,受台风“圆...
10-12 14:06:15
徐州一楼盘降价促销被叫停?官方:房开虚假宣传,已责令整改

徐州一楼盘降价促销被叫停?官方:房开虚假宣传,已责令整改

  澎湃新闻记者 邱海鸿  “工抵房”、降价近千元销售……近日,江苏徐州贾汪区一家楼盘因降价促销...
10-12 14:06:15
“云健身”成年轻人生活常态 互相“攀比”更起劲儿

“云健身”成年轻人生活常态 互相“攀比”更起劲儿

  “云健身”成年轻人生活常态 互相“攀比”更起劲儿  “开通会员参加运动在线培训,连续包月每月1...
10-12 14:06:14
“烫手山芋”?二手大件家具如何才能“有家可归”

“烫手山芋”?二手大件家具如何才能“有家可归”

  青年经济说“烫手山芋”?二手大件家具如何才能“有家可归”  大件家具回收成为社会经济进步中“...
10-12 14:06:14
云南到底有多美?谁没去过谁后悔……

云南到底有多美?谁没去过谁后悔……

  作者:王旌亚  地处中国西南部的云南省  素有  “动物王国”“植物王国”  和“物种基因库...
10-12 14:06:14
工人日报:让医保蛀虫无处遁形,确保医保基金安全

工人日报:让医保蛀虫无处遁形,确保医保基金安全

  本报评论员 韩韫超  骗保会伤及很多患者的权利。骗保横行,必然导致医保基金这个池子中的水量非...
10-12 14:06:14
用户感觉被“窃听” 个人信息安全如何保护

用户感觉被“窃听” 个人信息安全如何保护

  用户感觉被“窃听” 个人信息安全如何保护  很多人都有类似这样的经历:刚和朋友聊天提起某款商...
10-12 14:06:13
赢得年轻人喜爱的旅游商品更有市场

赢得年轻人喜爱的旅游商品更有市场

  赢得年轻人喜爱的旅游商品更有市场  一双会发热的运动鞋,同时具有定位和紧急求助功能;一套采用...
10-12 14:06:13
第十七届中国戏剧节开幕

第十七届中国戏剧节开幕

  第十七届中国戏剧节开幕  本报武汉10月11日电 (记者吴君)第十七届中国戏剧节日前在武汉开幕。本...
10-12 14:06:12
虎丘曲会 意味悠长

虎丘曲会 意味悠长

  虎丘曲会 意味悠长(文化市场新观察)  核心阅读  唱腔婉转,彩袖翻飞,日前在江苏苏州虎丘山风...
10-12 14:06:12
老街区成为新网红

老街区成为新网红

  老街区成为新网红(图说)  “这里有记忆中的乡愁。”临崖而建的步道、沿街点亮的路灯、巴渝特色的...
10-12 14:06:12
“中国时刻”开启 翻开全球生物多样性保护新篇章

“中国时刻”开启 翻开全球生物多样性保护新篇章

  “中国时刻”开启 翻开全球生物多样性保护新篇章  据了解,此次大会主题为“生态文明:共建地球...
10-12 14:06:12
除了登高插茱萸,重阳节还能干点啥

除了登高插茱萸,重阳节还能干点啥

  除了登高插茱萸,重阳节还能干点啥  “重阳”的名称,来自《易经》中的“以阳爻为九”。九月初九...
10-12 14:06:12
电池事故频发 近3亿辆电动自行车如何安全上路

电池事故频发 近3亿辆电动自行车如何安全上路

  电池事故频发 近3亿辆电动自行车如何安全上路  “小区物业应该为电动自行车提供相关条件。我们可...
10-12 14:06:12
出口同比增长1倍多 中国汽车何以畅销海外?

出口同比增长1倍多 中国汽车何以畅销海外?

  咱们的汽车何以畅销海外?  新能源汽车不断拓展欧洲市场,乘用车、商用车等各类车型畅销海外,中...
10-12 14:06:11
中国汽车国际竞争力持续提升

中国汽车国际竞争力持续提升

  中国汽车国际竞争力持续提升(开放谈)  进入新世纪以来,在国家鼓励发展自主品牌、鼓励自主创新、...
10-12 14:06:11
讲述长城文化带故事

讲述长城文化带故事

  讲述长城文化带故事  精美夺目的动物纹金带饰,神秘古朴的突厥石人像,华丽考究的契丹贵族马具…...
10-12 14:06:11
修缮“水下长城”

修缮“水下长城”

  修缮“水下长城”(记录中国)  在河北喜峰口、潘家口,有一段独特的“水下长城”。1975年修建潘家...
10-12 14:06:11

猫界“黄金比例”颜值榜出炉

  猫界“黄金比例”颜值榜出炉  提到美学,不少人会想到黄金分割定律或“黄金比例”。基于此的一项...
10-12 14:06:10
曾负伤未愈重回战场 不知经历已被拍成电影

曾负伤未愈重回战场 不知经历已被拍成电影

  曾负伤未愈重回战场 不知经历已被拍成电影  “长津湖是个地名,那一战,我们团的一营二连100多个...
10-12 14:06:10
从河南到山西,未来极端天气会越来越常见吗?专家解读来了

从河南到山西,未来极端天气会越来越常见吗?专家解读来了

  新闻1+1丨从河南到山西,未来极端天气会越来越常见吗?专家解读来了  进入10月,异常的强降雨造成...
10-12 14:06:10
全国约一半省份上调最低工资标准 哪些人群将受益?

全国约一半省份上调最低工资标准 哪些人群将受益?

  多地最低工资标准上调啦!  “新最低工资标准已正式执行”“上调标准来了,看看你能涨多少?”今...
10-12 14:06:10
创新居住体验 打造“智慧的家”

创新居住体验 打造“智慧的家”

  创新居住体验 打造“智慧的家”  “小优小优,我要做北京烤鸭。”随着主人一声令下,智能冰箱就...
10-12 14:06:10

为您推荐

精彩推送