《使用 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-clientyarn 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>Sign-in in progress... 正在登录中……
然后,需要在路由里配置好这个回调页面:
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文件。
给 API 请求添加认证头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 请求添加上认证头。前提是,后端接口也使用同样的 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标签:
截至2022年12月28日收盘,倍益康(870199)报收于25 58元,下跌0 27%,换手率0 77%,成交量758 27手,成交额193 75万元。12月
证券时报e公司讯,恒指早盘持续走高,截至午盘,收涨2 14%,恒生科技指数涨2 72%,电影概念、医美概念股早盘走高,教育板块、新能源汽车板块早
石狮4个村入选泉州乡村振兴成效显著村和实绩突出村
垒知集团:国泰君安关于垒知集团2022年持续督导培训情况的报告
2022年12月28日公告发布
全国柑橘面积基本稳定产量继续上升柑橘(桔子)是我们国家最主要的水果种类之一,前几年超过苹果而成为全国面积和产量最大的水果种类,面积300
国家卫健委对于新冠肺炎更名为新冠病毒,并实施乙类传染病,这对于股市情绪的修复,有着积极的意义。这三年以来,虽然国内货币政策持续宽松,
哈喽!大家好,我是元武。最近在浏览网页的时候发现《假面骑士圣刃》与《机界战队全开者》可能会进行剧场版联动,熟悉元武的朋友都知道,我只
上周沪深300指数下跌3 19%,上证综指下跌3 85%,深证成指下跌3 94%,创业板指下跌3 69%;分行业来看,上周无上涨板块。上周跌幅前三为:电力设备
同花顺数据中心显示,东华软件12月23日获融资买入640 69万元,占当日买入金额的22 25%,当前融资余额9 08亿元,占流通市值的5 48%,低于历史30
中新网杭州12月25日电(张煜欢)25日记者从浙江省疫情防控办获悉,浙江于近日印发《关于进一步落实关心关爱医务人员激励保障政策的通知》(下称“
掩藏爱意按理来说是比较简单的,但是对于有一些人来说,却是根本藏不住的,因为他们即使捂住了自己的嘴巴,爱意也会从眼睛里流露出来,就算是
↑点击蓝字关注极市平台|极市线上分享第107期|一直以来,为让大家更好地了解学界业界优秀的论文和工作,极市已邀请了超过100位技术大咖嘉宾,
12月23日,新希望琴牌将联合711便利店首发芋泥厚乳新品,并在上市初期发起“万瓶尝鲜”活动。 深受年轻人群追捧的芋泥风味,在即饮茶市...
腾讯的风控策略让普通用户抓狂经历是这样的,昨天有事要登录下QQ号,因为很久没用过QQ的缘故,现在是在一个新设备上登录,提示我需要扫码才能
12月22日智慧安防板块较上一交易日下跌0 7%,恒锋信息领跌。当日上证指数报收于3054 43,下跌0 46%。从资金流向上来看,当日智慧安防板块主力
空军首批“双学籍”女飞行学员顺利单飞——铿锵玫瑰舞蓝天 12月上旬,东北某机场,空军首批“双学籍”女飞行学员迎来蓝天生涯的首次单飞...
海创药业12月21日晚披露,公司近日收到美国食品药品监督管理局(以下简称“FDA”)的书面回复,公司自主研发的PROTAC药物HP518用于治疗转移性去
12月21日安硕信息发布公告《安硕信息:关于控股股东减持股份比例超过1%的公告》,其股东上海安硕科技发展有限公司于2022年6月29日至2022年12月2
李富真是韩国首富三星前会长李健熙的大女儿,现今三星会长李在镕的姐姐。李富真绝对是标准的白富美,并且个人能力非常的强悍。近两年来,李富
澎湃新闻记者庞静涛 12月20日,武汉市第四批集中供地的最后一宗地揭牌。10月28日,武汉市发布第四批次“两集中”出让公告,共推出各类用...
随着在加拿大蒙特利尔举行的联合国《生物多样性公约》第十五次缔约方大会(COP15)第二阶段会议临近尾声,大会会场内的中国角也于12月18日迎来最
当地时间12月19日,欧盟各国在布鲁塞尔举行的欧盟能源部长会议上达成协议,将天然气价格上限定在每兆瓦时180欧元。该限价机制将于2023年2月15
网贷逾期一般会上征信,有些借贷机构在用户逾期后一天后就会上报给征信机构,而有些借贷机构则是会在几天后上报给征信机构,因为有些借贷机构可
明明白白消费,留存消费凭证。医美消费因涉及医生、材料等选择,价格差异较大。消费者在接受医美服务前,一定要签订医疗美容服务合同,明确医
前情提要《使用IdentityServer保护Web应用(AntDPro前端+SpringBoot后端)》中记录了使用IdentitySer
南靖县领导调研农村污水治理工作
1、带壳的咸蛋直接置于干净的清水中煮熟或蒸熟都是可以的,但是需要注意的是如果是带壳的熟咸鸭蛋是不能放进微波炉里面加热的。2、因为带壳的咸
更详细的情况,一般是20元一份,2克。我们可以在一些小吃街买到这种食物,移植的成活率很高。一个沃根的热量大约是4466卡路里。购买原因。你敢
Copyright © 2015-2022 现在服装网版权所有 备案号:粤ICP备18023326号-5 联系邮箱:855 729 8@qq.com