首页 > 资讯 >

使用 IdentityServer 保护 Vue 前端

2022-12-19 16:49:57 来源:
前情提要

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

今日聚焦!深圳南山区将发2亿元消费券促消费

证券时报网讯,据深圳特区报公众号,12月18日,“HiGo南山·见圳美好生活”促消费活动正式启动。即日起...

2022-12-19

滴水贷逾期50年会上征信系统吗

网贷逾期一般会上征信,有些借贷机构在用户逾期后一天后就会上报给征信机构,而有些借贷机构则是会在几天...

2022-12-19

聚焦:小赢卡贷借款逾期3年还不起征信有什么影响

网贷逾期一般会上征信,有些借贷机构在用户逾期后一天后就会上报给征信机构,而有些借贷机构则是会在几天...

2022-12-18

V观财报|光正眼科收警示函 涉信披、商誉计提违规

光正眼科15日晚间公告,公司及相关人员收到新疆证监局警示函。上述共同投资构成关联交易,公司未履行审...

2022-12-17

今日最新!八爪鱼怎么清洗 八爪鱼清洗方法

1 刚买的章鱼,最好先用清水冲洗一下。2 洗净后,将章鱼放入锅中,加入适量的水和醋,反复揉搓数次,...

2022-12-17

当前讯息:cfa在德国就业前景,想知道的来看

cfa在德国的就业前景很好,金融行业本身的发展前景就不错,如果能够持有cfa证书那么会有更好的加成。在...

2022-12-16

ST新城董秘回复:公司一直在努力寻求多元化转型发展

ST新城(000809)12月16日在投资者关系平台上答复了投资者关心的问题。投资者:你好,近年来,公司年年卖...

2022-12-16

怎么查询信用卡欠款的详细流程?

二、电话查询拨打银行信用卡电话,转人工服务,即可要求客服查询您当前的欠款情况。有的银行开通微信公...

2022-12-15

头条焦点:首创环保: 首创环保第八届董事会2022年度第九次临时会议决议公告

首创环保:首创环保第八届董事会2022年度第九次临时会议决议公告

2022-12-15

世界热讯:宝钢股份:进口澳煤将对公司煤炭品种采购、结构调整带来积极作用,同时也能降低湛江基地的煤炭运输成本

(原标题:宝钢股份:进口澳煤将对公司煤炭品种采购、结构调整带来积极作用,同时也能降低湛江基地的煤...

2022-12-15

四川路桥: 北京康达律师事务所关于四川路桥2019年限制性股票激励计划首次授予部分第二个解除限售期、预留授予部分第一个解除限售期解除限售条件成就以及回购注销2019年限制性股票激励计划、2021年限制性股票激励计

四川省成都市东御街 18 号百扬大厦 1 栋 11 楼邮编:610000                  ...

2022-12-14

绿康生化(002868)12月14日主力资金净卖出1174.38万元

截至2022年12月14日收盘,绿康生化(002868)报收于57 53元,上涨5 75%,换手率2 29%,成交量3 49万手...

2022-12-14

全球微动态丨索菲亚:12月13日获融资买入1217.67万元,占当日流入资金比例11.92%

同花顺数据中心显示,索菲亚12月13日获融资买入1217 67万元,占当日买入金额的11 92%,当前融资余额2...

2022-12-14

热点评!美国造车新势力Lucid开始在华招人 不久前被马斯克暗示即将倒闭

【美国造车新势力Lucid开始在华招人不久前被马斯克暗示即将倒闭】中国新能源汽车市场或将迎来又一海外强...

2022-12-13

环球观天下!皇氏集团增资皇氏农光获控制权 光伏板块子公司纳入合并报表

皇氏集团(002329)光伏产业布局逐渐清晰。  12月12日晚间公告显示,皇氏集团与与深圳市奕鸣新能源有限...

2022-12-13

天天快看点丨男方有网贷女方需要还吗

男方的网贷信用卡的赌债不属于夫妻共同债务,女方不需要偿还。夫妻共同债务是指为满足夫妻共同生活需要...

2022-12-13

每日快讯!《绝地追击》首曝预告高至霆演绎武警酷帅有型

Yes娱乐12月12日讯近日,由邱礼涛执导、高至霆主演的灾难动作电影《绝地追击》首次发布预告。该片讲述了...

2022-12-12

最新:喜悦智行:公司将会按照证监会、深交所的相关规定在定期报告中披露相关股东人数,敬请关注公司相关公告

喜悦智行(301198)12月12日在投资者关系平台上答复了投资者关心的问题。投资者:请问截至2022年12月10日...

2022-12-12

最新:罗莱生活董秘回复:公司于2022年8月公告以自有资金取得工业用地,用以建设南通新总部和罗莱智慧产业园区

罗莱生活(002293)12月09日在投资者关系平台上答复了投资者关心的问题。投资者:请问贵司新的产能扩建预...

2022-12-09

每日观点:大众汽车将投资近5亿美元改造沃尔夫斯堡工厂?以生产电动汽车

【TechWeb】12月8日消息,据国外媒体报道,大众汽车将在2025年初前投资近5亿美元,对其沃尔夫斯堡生产工...

2022-12-08

今日聚焦!【机构调研记录】朱雀基金调研海创药业、欧科亿等5只个股(附名单)

根据市场公开信息及12月6日披露的机构调研信息,朱雀基金近期对5家上市公司进行了调研,相关名单如下:1...

2022-12-07

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

口述者:社区志愿者Jacob(荷兰裔新西兰人)采访记者:张懿 通讯员:韩海峰 地处松江区的东明花苑小区,这...

2022-04-22

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

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

2022-04-22

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

(上海战疫录)为何要高频度核酸检测?上海相关部门回应 中新网上海4月22日电 (周卓傲)上海从4月22日起开...

2022-04-22

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

山东新增本土无症状感染者23例

杭州拱墅区今日5点起开展全员核酸检测

Copyright @  2015-2022 太平洋家电网版权所有  备案号: 豫ICP备2022016495号-17   联系邮箱:93 96 74 66 9@qq.com