首页 > 电视 > > 正文

使用 IdentityServer 保护 Vue 前端-焦点报道

2022-12-20 05:09:42 来源:
前情提要

《使用 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

标签:

使用 IdentityServer 保护 Vue 前端-焦点报道

前情提要《使用IdentityServer保护Web应用(AntDPro前端+SpringBoot后端)》中记录了使用IdentitySer

2022-12-20 05:09:42

大名城:定增夸大投资额了吗

大名城定增的项目多数已基本完成建设,但其投资额都较年报、半年报中多出上亿元。  杨现华/文  在...

2022-12-19 17:32:29

双乐股份董秘回复:感谢您宝贵的建议,后续若有公司会按照相关要求,积极履行信息披露的义务

双乐股份(301036)12月19日在投资者关系平台上答复了投资者关心的问题。投资者:尊敬的董秘您好:我是来自...

2022-12-19 12:28:44

焦点播报:鄂州二级工伤赔偿期限怎么规定

职工因工致残被鉴定为一级至四级伤残的,保留劳动关系,退出工作岗位,享受以下待遇:(一)从工伤保险...

2022-12-19 06:43:19

西藏天路: 西藏天路公司章程(2022年12月 修订草案)

西藏天路股份有限公司     章            程(2022 年 12 月 修订草案)    ...

2022-12-18 18:02:24

张子枫练成直角肩后像换了个人!“假小子”风也能很温柔,有学到

在日常穿搭的过程中,总是会发现各种问题,就连很多艺人名人都是这样的。就像张子枫妹妹就是一个很好的...

2022-12-17 19:56:38

快资讯:兖矿能源(600188)12月16日主力资金净买入1578.20万元

截至2022年12月16日收盘,兖矿能源报收于37 77元,上涨1 12%,换手率0 42%,成交量12 65万手,成交...

2022-12-17 07:52:32

游戏账号长时间未登录会被删除?热门卡牌手游公司被告了 当前播报

)如果用户长时间不登录游戏账号,游戏公司有权直接删除该账号及账号下的游戏数据和相关信息吗。12月15...

2022-12-16 18:56:48

抖音好物年货节将推【跨店每满减】玩法 商家可享四大特权:时快讯

编程客栈()12月16日消息:今日,抖音宣布好物年货节即将启幕,平台主推玩法【跨店每满减】来袭,本次年...

2022-12-16 12:01:11

木瓜保存方法时间长 木瓜的保存方式

1 木瓜是一种水果,不能放在冰箱里保存。木瓜只要沾水,就会有黑斑。虽然冰箱有吸水的作用,但是一旦取...

2022-12-16 03:18:33

从“代餐”到“正餐”糖尿病功能性食品竞逐主食赛道-世界关注

从“代餐”到“正餐”糖尿病功能性食品竞逐主食赛道2022年12月15日17:26中国网财经

2022-12-15 17:15:11

网易智企亮相2022世界直播电商大会,发布直播电商护航解决方案

12月12日,2022世界直播电商大会在在杭州国际博览中心圆满落幕,本次大会围绕“电商数字化直播共发展”...

2022-12-15 11:29:43

创4学员势力榜:刘宇稳坐第一,张嘉元上升到第三,林墨跌至第五! 世界简讯

这一届的《创造营2021》可以说是神仙打架,前面两期就已经出现了很多的热门选手了,不管是舞蹈实力还是...

2022-12-15 01:35:06

万人助万企|西峡双龙镇:深入一线办实事 助力企业“加速跑”-天天通讯

为贯彻落实省、市、县“万人助万企”活动部署要求,着力解决企业发展的难点、痛点、堵点问题,打造一流...

2022-12-14 15:48:06

在小红书上做哪些副业,月入10w不是梦

最近收到之前品牌医生的会员给到的成长反馈,特别为她开心。原本做小红书账号为了给自己的品牌引流卖货...

2022-12-14 09:56:06

明阳智能: 2023年第一次临时股东大会材料_世界百事通

明阳智慧能源集团股份公司  召开时间:2023 年 1 月 11 日                  ...

2022-12-13 20:36:31

12月12日基金净值:广发中证基建工程ETF最新净值1.1358,跌2.21%

12月12日,广发中证基建工程ETF最新单位净值为1 1358元,累计净值为1 1358元,较前一交易日下跌2 21%...

2022-12-13 12:53:15

猴头菇的作用与功功效(猴头菇对脾虚有帮助吗)

加米助消化。功能:健脾益气。猴头菇是猴头菇的子实体,猴头菇是一种属于牙科家族的真菌。有助于消化,对...

2022-12-13 04:42:06

如在画中:每日关注

扫码看更多美图如在画中进入冬季,山城区汤河水库小岛上的树叶变得金黄一片,宛如一幅色彩明亮的油画。...

2022-12-12 16:15:46

当前通讯!帕瓦股份投资成立循环科技公司,含常用有色金属冶炼业务

(原标题:帕瓦股份投资成立循环科技公司,含常用有色金属冶炼业务)企查查APP显示,近日,兰溪博观循环...

2022-12-12 10:50:35

天天快报!本周盘点(12.5-12.9):中化国际周涨2.91%,主力资金合计净流出4119.68万元

截至2022年12月9日收盘,中化国际(600500)报收于7 43元,较上周的7 22元上涨2 91%。本周,中化国际...

2022-12-09 15:42:07

12月8日永泰运涨停分析:快递物流,长三角一体化概念热股

永泰运涨停收盘,收盘价57 75元。该股于10点44分涨停,未打开涨停,截止收盘封单资金为5074 12万元,...

2022-12-08 15:12:31

抗病毒面料板块集体走强,凤竹纺织等多股涨停 每日热点

格隆汇12月7日丨抗病毒面料板块集体走强,南山智尚涨超12%,凤竹纺织、新澳股份、力合科创、如意集团涨...

2022-12-07 11:36:38

京东发布一季度财报 快递小哥平均月薪过万引发热议

5月17日,京东物流发布2022年一季度业绩报告。数据显示,2022年一季度,京东物流总收入274亿元,同比增...

2022-05-20 14:53:08

北京朝阳区发现1例新冠核酸检测初筛阳性

4月22日,北京市朝阳区发现1例新冠核酸检测初筛阳性,现住朝阳区垡头西里38号楼。朝阳区已第一时间启动...

2022-04-22 09:52:52

外籍志愿者“老罗”:战“疫”让我感受到“长征精神”

广东新增本土确诊病例5例 新增本土无症状感染者1例

31省份新增本土确诊病例2119例 新增本土无症状感染者16383例

广东专家团队:限时饮食干预与常规能量限制同样有效

“反诈警官老陈”:面对网络争议,我驾驭不住流量了

上海六人因伪造、买卖通行证被采取刑事强制措施

医保基金是“救命钱”,需人人捍卫

上海这个大型社区探索防控新路:划一块 清一块 解封一块

为何要高频度核酸检测?上海相关部门回应

黑龙江新增本土确诊34例、本土无症状感染者56例

河北新增本土确诊病例1例、本土无症状感染者77例

南方地区将有明显降水 冷空气影响东北华北等地

南方降雨再度发展雨水频繁到月底 北方气温多起伏

安徽新增无症状感染者28例

云南保山捐赠的铁皮石斛、茶叶被偷拿?上海闵行区回应

河南新增本土确诊病例3例、本土无症状感染者14例

上海全市性的封控还会持续多久?相关部门回应

云南新增2例本土确诊病例 9例本土无症状感染者

为何简、简什么、怎么简?对话“极简生活”的年轻人

对话“抗癌考研”女生:学习和奋斗让生活重回正轨

年轻人找工作莫让“山寨证书”绊住脚

海南新增3例本土确诊病例

山西新增本土确诊病例3例、无症状感染者16例

北京新增1例本土确诊病例

紧盯“围猎” 湖南通报5起向县区委书记行贿典型案例

x 广告
x 广告

Copyright @  2015-2022 亚洲家电网版权所有  备案号: 豫ICP备20022870号-9   联系邮箱:553 138 779@qq.com