使用 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)
陕西彬长矿业公司胡家河矿发生一起局部冒顶事故致4人死亡

陕西彬长矿业公司胡家河矿发生一起局部冒顶事故致4人死亡

  新华社西安10月12日电(记者薛天、张思洁)记者从陕西煤业化工集团有限公司及咸阳市委宣传部获悉,10...
10-12 14:06:21
京秦高速遵秦段加紧施工建设

京秦高速遵秦段加紧施工建设

  目前,由中建路桥集团参与承建的京秦高速公路遵(遵化)秦(秦皇岛)段正在加紧施工,各项工程进展顺利...
10-12 14:06:21
护航法治中国行稳致远

护航法治中国行稳致远

  【坚持和完善人民代表大会制度】   检查21部法律和1个决定的实施情况,听取审议“一府一委两院”...
10-12 14:06:21
记录历史的耄耋老兵:让家乡的英雄故事永流传

记录历史的耄耋老兵:让家乡的英雄故事永流传

  中新网石家庄10月12日电 题:记录历史的耄耋老兵:让家乡的英雄故事永流传  作者 赵丹媚  见...
10-12 14:06:21
山西因灾停电用户95%以上已恢复供电

山西因灾停电用户95%以上已恢复供电

  新华社太原10月12日电(记者梁晓飞)记者12日从国网山西省电力公司了解到,受近日强降雨影响,山西运...
10-12 14:06:20
浙江仙都黄帝祭典弦歌不绝 慎终追远赓续中华根脉

浙江仙都黄帝祭典弦歌不绝 慎终追远赓续中华根脉

  中新网丽水10月12日电(记者 范宇斌)四海同心祭始祖,共同富裕启华章。辛丑(2021)年中国仙都祭祀轩...
10-12 14:06:20
教育部:校外培训机构登记为非营利前暂停招生收费

教育部:校外培训机构登记为非营利前暂停招生收费

  记者12日从教育部了解到,教育部校外教育培训监管司近日就校外培训机构“营改非”工作作出部署,要...
10-12 14:06:20
山西介休部分村庄启动灾后消杀防疫

山西介休部分村庄启动灾后消杀防疫

  中新网晋中10月12日电 (记者 陆祁国)随着抽排洪水作业进度加快,部分村庄积滞洪水水位明显下降。1...
10-12 14:06:20
中国新疆“河狸公主”:一百万中国青年救助保护河狸

中国新疆“河狸公主”:一百万中国青年救助保护河狸

  (生物多样性大会)中国新疆“河狸公主”:一百万中国青年救助保护河狸  中新社昆明10月12日电 题...
10-12 14:06:20
“母亲河畔的中国”网络主题活动在河南开封启动

“母亲河畔的中国”网络主题活动在河南开封启动

  中新网开封10月12日电 12日上午,“母亲河畔的中国”网络主题活动启动仪式在河南开封举行。  本...
10-12 14:06:20
陕煤彬长公司一煤矿发生局部冒顶事故 4人死亡

陕煤彬长公司一煤矿发生局部冒顶事故 4人死亡

  记者从陕西省咸阳市委宣传部获悉,10月11日13时50分许,陕煤彬长公司胡家河煤矿402104工作面发生局...
10-12 14:06:19
广东海警局联合广东省公安厅开展“清湾行动” 查获非法船舶860艘

广东海警局联合广东省公安厅开展“清湾行动” 查获非法船舶860艘

  中新网北京10月12日电 为坚决遏制珠江口水域走私活动多发态势,坚决打击违法犯罪分子嚣张气焰,全...
10-12 14:06:19
浙江长兴公安摧毁一盗掘古墓犯罪团伙 追回文物40余件

浙江长兴公安摧毁一盗掘古墓犯罪团伙 追回文物40余件

  中新网湖州10月12日电(施紫楠 吴俊杰)在小说和影视剧中,盗墓者常被称为“摸金校尉”,十分神秘。...
10-12 14:06:19
山西 陕西两地加紧防汛救灾

山西 陕西两地加紧防汛救灾

  央视网消息(新闻联播):山西、陕西两地加紧防汛救灾。今天(10月11日),财政部、应急管理部向两省紧...
10-12 14:06:19
强降雨致山西公路灾损6021.36公里

强降雨致山西公路灾损6021.36公里

  记者今天(10月12日)从山西省人民政府召开的新闻发布会上了解到,受连续强降雨影响,山西公路交通基...
10-12 14:06:19
哈尔滨多地风险等级调整为低风险

哈尔滨多地风险等级调整为低风险

  中新网哈尔滨10月12日电 (记者 刘锡菊)12日,哈尔滨市应对新冠肺炎疫情工作指挥部发布关于调整哈...
10-12 14:06:19
南京破获一起非法制作出租游戏账号案:未成年人5元租个账号就能打游戏

南京破获一起非法制作出租游戏账号案:未成年人5元租个账号就能打游戏

  中新网南京10月12日电 (记者 申冉)非法购买大量个人信息,与游戏账号进行绑定,制成经过“实名认...
10-12 14:06:18
10月2日至7日 山西出现有气象记录以来秋季最强降水过程

10月2日至7日 山西出现有气象记录以来秋季最强降水过程

  记者今天从山西省人民政府召开的新闻发布会上了解到,6月份入汛以来,受低涡切变线和西太平洋副热带...
10-12 14:06:18
台风“圆规”将于13日下午到夜间登陆海南岛

台风“圆规”将于13日下午到夜间登陆海南岛

  中新网海口10月12日电 (符晓虹 李凡 翁小芳)据海南省气象台12日介绍,今年第18号台风“圆规”(强...
10-12 14:06:18
哈尔滨11日新增治愈出院本土确诊病例15例

哈尔滨11日新增治愈出院本土确诊病例15例

  中新网哈尔滨10月12日电 (记者 刘锡菊)12日,哈尔滨市卫健委发布哈尔滨市10月11日0-24时疫情通报...
10-12 14:06:18
涉案金额756亿元!甘肃特大地下钱庄案终告破

涉案金额756亿元!甘肃特大地下钱庄案终告破

  外汇管理部门与公安机关日前在甘肃联合破获一起特大地下钱庄案件,涉案金额高达756亿元,沉重打击了...
10-12 14:06:17
强降雨致山西因灾死亡15人 直接经济损失50.29亿元

强降雨致山西因灾死亡15人 直接经济损失50.29亿元

  今天(10月12日)上午10时,山西省召开防汛救灾新闻发布会,通报相关情况。  记者今天从山西省人民...
10-12 14:06:17
强降雨致山西因灾死亡15人 直接经济损失50.29亿元

强降雨致山西因灾死亡15人 直接经济损失50.29亿元

  中新网10月12日电 10月12日,山西省召开防汛救灾新闻发布会,通报相关情况。据介绍,截至目前,此...
10-12 14:06:17
特写:养老院的78位老人:雨过天晴,我们回家

特写:养老院的78位老人:雨过天晴,我们回家

  中新网晋中10月12日电 题:养老院的78位老人:雨过天晴,我们回家  中新网记者 杨杰英  “洪...
10-12 14:06:17
新型诈骗套路难防“领导”喊你转账,转吗?

新型诈骗套路难防“领导”喊你转账,转吗?

  “领导”加你微信,关心你的工作和生活,还约你到他办公室安排工作?先别激动,这可能是一场网络骗...
10-12 14:06:17
10月以来山西发生地质灾害33起 地质灾害防治工作形势非常严峻

10月以来山西发生地质灾害33起 地质灾害防治工作形势非常严峻

  10月以来山西发生地质灾害33起 地质灾害防治工作形势非常严峻  记者今天(10月12日)从山西省人民...
10-12 14:06:17
付款不被骗、上网不留痕……这些“黑科技”现身2021年国家网络安全宣传周

付款不被骗、上网不留痕……这些“黑科技”现身2021年国家网络安全宣传周

  在反诈盲盒中体验如何保住自己的“钱袋子”,在现场观摩如何安全上网不留痕迹,大型油气企业如何远...
10-12 14:06:16
受台风“圆规”影响 福建多处景点关闭

受台风“圆规”影响 福建多处景点关闭

  受今年第18号台风“圆规”及冷空气共同影响,福建省附近海上风力逐渐加大,为确保安全,自2021年10...
10-12 14:06:16
浙江女子10天前看人杀鸭感染鹦鹉热:39℃高烧 乏力干咳

浙江女子10天前看人杀鸭感染鹦鹉热:39℃高烧 乏力干咳

  浙江女子突发39℃高烧,路都走不了!近期出现一人感染后身亡,医生紧急提醒……  “乏力,发热,...
10-12 14:06:16
95后姑娘坚持画云千余天 网友:温柔笔触里有浪漫诗意

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

  95后湖北姑娘坚持画云千余天   千万网友称赞:她温柔的笔触里有种浪漫的诗意  你喜欢看云吗?...
10-12 14:06:16

为您推荐

精彩推送