Commit 3a095c601c4989bbb503b318c1fcfff5f88d7a4d

Authored by ww
1 parent 7783af89

perf(share page): 优化分享页面的携带token影响当前用户在IOT平台操作

... ... @@ -4,8 +4,8 @@ import type { AxiosTransform, CreateAxiosOptions } from '@/utils/external/http/a
4 4 import { useGlobSetting } from '@/hooks/external/setting';
5 5 import { RequestEnum, ContentTypeEnum } from '@/enums/external/httpEnum';
6 6 import { isString } from '@/utils/external/is';
7   -import { getJwtToken } from '@/utils/external/auth';
8   -import { setObjToUrlParams, deepMerge } from '@/utils/external';
  7 +import { getJwtToken, getShareJwtToken } from '@/utils/external/auth';
  8 +import { setObjToUrlParams, deepMerge } from '@/utils/external';
9 9 import { formatRequestDate, joinTimestamp } from '@/utils/external/http/axios/helper';
10 10 import { VAxios } from '@/utils/external/http/axios/Axios';
11 11 import { checkStatus } from './checkStatus';
... ... @@ -84,15 +84,25 @@ const transform: AxiosTransform = {
84 84 */
85 85 requestInterceptors: (config, options) => {
86 86 // 请求之前处理config
87   - const token = getJwtToken();
88   - if (token && (config as Recordable)?.requestOptions?.withToken !== false) {
89   - // jwt token
90   - config.headers!['X-Authorization'] = options.authenticationScheme
91   - ? `${options.authenticationScheme} ${token}`
92   - : token as string;
  87 + const { requestOptions } = config;
  88 + const { withShareToken } = requestOptions || {};
  89 + const { requestOptions: { withToken } = {} } = options;
  90 + if (withToken !== false) {
  91 + const shareToken = getShareJwtToken();
  92 + if (withShareToken && shareToken) {
  93 + config.headers!['X-Authorization'] = options.authenticationScheme
  94 + ? `${options.authenticationScheme} ${shareToken}`
  95 + : shareToken;
  96 + } else {
  97 + const token = getJwtToken();
  98 + if (token) {
  99 + config.headers!['X-Authorization'] = options.authenticationScheme
  100 + ? `${options.authenticationScheme} ${token}`
  101 + : token;
  102 + }
  103 + }
93 104 }
94   -
95   - return config;
  105 + return config
96 106 },
97 107
98 108 /**
... ... @@ -114,7 +124,7 @@ const transform: AxiosTransform = {
114 124 ? response?.data?.message || response?.data?.msg
115 125 : response?.data;
116 126
117   - const flag = checkStatus(error?.response?.status, msg, errorMessageMode);
  127 + const flag = checkStatus(error?.response?.status, msg, errorMessageMode);
118 128 return Promise.reject(response?.data);
119 129 },
120 130 };
... ... @@ -158,7 +168,7 @@ function createAxios(opt?: Partial<CreateAxiosOptions>) {
158 168 // 忽略重复请求
159 169 ignoreCancelToken: true,
160 170 // 是否携带token
161   - withToken: false
  171 + withToken: true
162 172 },
163 173 },
164 174 opt || {}
... ...
1 1 import { RequestBodyEnum, RequestParams } from "@/enums/httpEnum"
2 2 import { ExtraRequestConfigType } from "@/store/external/modules/extraComponentInfo.d"
3 3 import { RequestConfigType } from "@/store/modules/chartEditStore/chartEditStore.d"
  4 +import { isShareMode } from "@/views/share/hook"
4 5 import { customHttp } from "./http"
5 6
6 7 export enum ParamsType {
... ... @@ -103,7 +104,7 @@ export const customRequest = async (request: RequestConfigType) => {
103 104 }
104 105
105 106 const body = transformBodyValue(Body, requestParamsBodyType)
106   -
  107 +
107 108 return customHttp.request<any>({
108 109 url: requestUrl,
109 110 baseURL: getOriginUrl(requestOriginUrl!),
... ... @@ -113,6 +114,7 @@ export const customRequest = async (request: RequestConfigType) => {
113 114 headers: extraValue(Header)
114 115 }, {
115 116 joinPrefix: false,
116   - apiUrl: ''
  117 + apiUrl: '',
  118 + withShareToken: isShareMode()
117 119 })
118 120 }
... ...
1 1 import { ViewTypeEnum } from "@/enums/external/viewEnum"
2 2 import { defHttp } from "@/utils/external/http/axios"
  3 +import { isShareMode } from "@/views/share/hook"
3 4
4 5 enum Api {
5 6 TOKEN = '/auth/login/public',
... ... @@ -17,7 +18,7 @@ export const getPublicToken = (publicId: string) => {
17 18 return defHttp.post<Record<'token' | 'refreshToken', string>>({
18 19 url: Api.TOKEN,
19 20 data: { publicId }
20   - }, { joinPrefix: false })
  21 + }, { joinPrefix: false, withShareToken: isShareMode() })
21 22 }
22 23
23 24 /**
... ... @@ -27,7 +28,7 @@ export const getPublicToken = (publicId: string) => {
27 28 export const checkSharePageNeedAccessToken = (id: string) => {
28 29 return defHttp.get<{ data: boolean }>({
29 30 url: `${Api.CHECK}/${ViewTypeEnum.LARGE_SCREEN}/${id}`
30   - })
  31 + }, { withShareToken: isShareMode() })
31 32 }
32 33
33 34 /**
... ... @@ -39,5 +40,5 @@ export const getShareContentData = (options: Record<'id' | 'accessCredentials',
39 40 return defHttp.get<{ data: any }>({
40 41 url: `${Api.SHARE_CONTENT}/${ViewTypeEnum.LARGE_SCREEN}/share_data/${options.id}`,
41 42 params: accessCredentials ? { accessCredentials } : {}
42   - })
  43 + }, { withShareToken: isShareMode() })
43 44 }
... ...
... ... @@ -5,6 +5,10 @@ export const JWT_TOKEN_KEY = 'JWT_TOKEN';
5 5
6 6 export const REFRESH_TOKEN_KEY = 'REFRESH_TOKEN';
7 7
  8 +export const SHARE_JWT_TOKEN_KEY = 'SHARE_JWT_TOKEN';
  9 +
  10 +export const SHARE_REFRESH_TOKEN_KEY = 'SHARE_REFRESH_TOKEN';
  11 +
8 12 export const LOCALE_KEY = 'LOCALE__';
9 13
10 14 // user info key
... ...
... ... @@ -3,10 +3,11 @@ import { CreateComponentType } from "@/packages/index.d";
3 3 import { useSocketStore } from "@/store/external/modules/socketStore";
4 4 import { SocketReceiveMessageType } from "@/store/external/modules/socketStore.d";
5 5 import { useChartEditStore } from "@/store/modules/chartEditStore/chartEditStore";
6   -import { getJwtToken } from "@/utils/external/auth";
  6 +import { getJwtToken, getShareJwtToken } from "@/utils/external/auth";
7 7 import { useWebSocket, WebSocketResult } from "@vueuse/core";
8 8 import { onMounted, unref } from "vue";
9 9 import { ExtraRequestConfigType } from "@/store/external/modules/extraComponentInfo.d";
  10 +import { isShareMode } from "@/views/share/hook";
10 11
11 12
12 13 interface SocketConnectionPoolType {
... ... @@ -39,7 +40,7 @@ const getSocketInstance = (request: ExtraRequestConfigType) => {
39 40 if (~index) {
40 41 return socketConnectionPool[index].ws
41 42 }
42   - const token = getJwtToken()
  43 + const token = isShareMode() ? getShareJwtToken() : getJwtToken()
43 44 const socketUrl = `${getOriginUrl(requestOriginUrl || '')}${requestUrl}?token=${token}`
44 45
45 46 const instance = useWebSocket(socketUrl, {
... ...
... ... @@ -3,7 +3,7 @@ import type { ErrorMessageMode } from '/#/external/axios';
3 3 import { defineStore } from 'pinia';
4 4 import { pinia as store } from '@/store';
5 5 import { RoleEnum } from '@/enums/external/roleEnum';
6   -import { JWT_TOKEN_KEY, REFRESH_TOKEN_KEY, ROLES_KEY, USER_INFO_KEY } from '@/enums/external/cacheEnum';
  6 +import { JWT_TOKEN_KEY, REFRESH_TOKEN_KEY, ROLES_KEY, SHARE_JWT_TOKEN_KEY, SHARE_REFRESH_TOKEN_KEY, USER_INFO_KEY } from '@/enums/external/cacheEnum';
7 7 import { getAuthCache, getJwtToken, getRefreshToken, setAuthCache } from '@/utils/external/auth';
8 8 import {
9 9 LoginParams,
... ... @@ -29,6 +29,8 @@ interface UserState {
29 29 lastUpdateTime: number;
30 30 jwtToken?: string;
31 31 refreshToken?: string;
  32 + shareJwtToken?: string;
  33 + shareRefreshToken?: string;
32 34 outTarget?: string;
33 35 }
34 36
... ... @@ -47,6 +49,8 @@ export const useUserStore = defineStore({
47 49 jwtToken: getJwtToken() as string || undefined,
48 50 //refresh Token
49 51 refreshToken: getRefreshToken() as string || undefined,
  52 + shareJwtToken: undefined,
  53 + shareRefreshToken: undefined,
50 54 // roleList
51 55 roleList: [],
52 56 // Whether the login expired
... ... @@ -96,6 +100,12 @@ export const useUserStore = defineStore({
96 100 setAuthCache(JWT_TOKEN_KEY, jwtToken);
97 101 setAuthCache(REFRESH_TOKEN_KEY, refreshToken);
98 102 },
  103 + storeShareToken(jwtToken: string, refreshToken: string) {
  104 + this.shareJwtToken = jwtToken;
  105 + this.shareRefreshToken = refreshToken;
  106 + setAuthCache(SHARE_JWT_TOKEN_KEY, jwtToken);
  107 + setAuthCache(SHARE_REFRESH_TOKEN_KEY, refreshToken);
  108 + },
99 109 setToken(info: string | undefined) {
100 110 this.jwtToken = info;
101 111 setAuthCache(JWT_TOKEN_KEY, info);
... ... @@ -152,14 +162,6 @@ export const useUserStore = defineStore({
152 162 }
153 163 return userInfo;
154 164 },
155   - async smsCodelogin(
156   - params: SmsLoginParams & {
157   - goHome?: boolean;
158   - mode?: ErrorMessageMode;
159   - }
160   - ) {
161   -
162   - },
163 165 async getMyUserInfoAction() {
164 166 const userInfo = await getMyInfo();
165 167 this.setUserInfo(userInfo);
... ... @@ -193,6 +195,20 @@ export const useUserStore = defineStore({
193 195 },
194 196
195 197 /**
  198 + * @description 刷新分享页面的token
  199 + */
  200 + async doShareRefresh() {
  201 + try {
  202 + const req = { refreshToken: this.shareRefreshToken } as RefreshTokenParams
  203 + const { token, refreshToken } = await doRefreshToken(req)
  204 + this.storeShareToken(token, refreshToken)
  205 + } catch (error) {
  206 + window.location.reload()
  207 + throw error
  208 + }
  209 + },
  210 +
  211 + /**
196 212 * @description: Confirm before logging out
197 213 */
198 214 confirmLoginOut() {
... ...
1 1 import { Persistent, BasicKeys } from '@/utils/external/cache/persistent';
2   -import { CacheTypeEnum } from '@/enums/external/cacheEnum';
  2 +import { CacheTypeEnum, SHARE_JWT_TOKEN_KEY, SHARE_REFRESH_TOKEN_KEY } from '@/enums/external/cacheEnum';
3 3 import projectSetting from '@/settings/external/projectSetting';
4 4 import { JWT_TOKEN_KEY, REFRESH_TOKEN_KEY } from '@/enums/external/cacheEnum';
5 5
... ... @@ -20,9 +20,17 @@ export function clearAuthCache(immediate = true) {
20 20 const fn = isLocal ? Persistent.clearLocal : Persistent.clearSession;
21 21 return fn(immediate);
22 22 }
23   -export function getJwtToken() {
  23 +export function getJwtToken(): string {
24 24 return getAuthCache(JWT_TOKEN_KEY);
25 25 }
26   -export function getRefreshToken() {
  26 +export function getRefreshToken(): string {
27 27 return getAuthCache(REFRESH_TOKEN_KEY);
28 28 }
  29 +
  30 +export function getShareJwtToken(): string {
  31 + return getAuthCache(SHARE_JWT_TOKEN_KEY);
  32 +}
  33 +export function getShareRefreshToken(): string {
  34 + return getAuthCache(SHARE_REFRESH_TOKEN_KEY);
  35 +}
  36 +
... ...
... ... @@ -17,9 +17,11 @@ import {
17 17 APP_SESSION_CACHE_KEY,
18 18 MULTIPLE_TABS_KEY,
19 19 MENU_LIST,
  20 + SHARE_JWT_TOKEN_KEY,
  21 + SHARE_REFRESH_TOKEN_KEY,
20 22 } from '@/enums/external/cacheEnum';
21 23 import { DEFAULT_CACHE_TIME } from '@/settings/external/encryptionSetting';
22   -import { toRaw } from 'vue';
  24 +import { toRaw } from 'vue';
23 25 import omit from 'lodash/omit';
24 26 import pick from 'lodash/pick';
25 27
... ... @@ -34,6 +36,8 @@ interface BasicStore {
34 36 [PROJ_CFG_KEY]: ProjectConfig;
35 37 [MULTIPLE_TABS_KEY]: RouteLocationNormalized[];
36 38 [MENU_LIST]: any[];
  39 + [SHARE_JWT_TOKEN_KEY]: string
  40 + [SHARE_REFRESH_TOKEN_KEY]: string
37 41 }
38 42
39 43 type LocalStore = BasicStore;
... ...
1   -import type { AxiosRequestConfig, AxiosInstance, AxiosResponse, AxiosError } from 'axios';
2   -import type { CreateAxiosOptions } from './axiosTransform';
  1 +import type { AxiosInstance, AxiosResponse, AxiosError } from 'axios';
  2 +import type { AxiosRequestConfig, CreateAxiosOptions } from './axiosTransform';
3 3 import axios from 'axios';
4 4 import qs from 'qs';
5 5 import { AxiosCanceler } from './axiosCancel';
... ... @@ -115,13 +115,21 @@ export class VAxios {
115 115 this.axiosInstance.interceptors.request.use(async (config: AxiosRequestConfig) => {
116 116 // If cancel repeat request is turned on, then cancel repeat request is prohibited
117 117 const userStore = useUserStore();
118   - if (userStore && userStore.jwtToken) {
  118 + // if (userStore && (userStore.jwtToken || userStore.shareJwtToken)) {
  119 + if (userStore) {
119 120 try {
120   - const res = jwt_decode(userStore.jwtToken) as JwtModel;
121   - const currentTime = (new Date().getTime() + (config.timeout || 0)) / 1000;
122   - if (currentTime >= res.exp && this.isNeedTokenURL(config.url!)) {
123   - await this.refreshTokenBeforeReq(userStore.doRefresh);
  121 + const { requestOptions = {} } = config
  122 + const { withShareToken, withToken } = requestOptions
  123 + const token = withShareToken && withToken ? userStore.shareJwtToken : userStore.jwtToken
  124 + const doRefresh = withShareToken && withToken ? userStore.doShareRefresh : userStore.doRefresh
  125 + if (token) {
  126 + const res = jwt_decode(token) as JwtModel;
  127 + const currentTime = (new Date().getTime() + (config.timeout || 0)) / 1000;
  128 + if (currentTime >= res.exp && this.isNeedTokenURL(config.url!)) {
  129 + await this.refreshTokenBeforeReq(doRefresh);
  130 + }
124 131 }
  132 +
125 133 } catch (error) {
126 134 userStore.logout();
127 135 }
... ...
1 1 /**
2 2 * Data processing class, can be configured according to the project
3 3 */
4   -import type { AxiosRequestConfig, AxiosResponse } from 'axios';
  4 +import type { AxiosRequestConfig as OriginAxiosRequestConfig, AxiosResponse } from 'axios';
5 5 import type { RequestOptions, Result } from '/#/external/axios';
6 6
7 7 export interface CreateAxiosOptions extends AxiosRequestConfig {
... ... @@ -11,6 +11,8 @@ export interface CreateAxiosOptions extends AxiosRequestConfig {
11 11 requestOptions?: RequestOptions;
12 12 }
13 13
  14 +export type AxiosRequestConfig = OriginAxiosRequestConfig & {requestOptions?: RequestOptions}
  15 +
14 16 export abstract class AxiosTransform {
15 17 /**
16 18 * @description: Process configuration before request
... ...
... ... @@ -9,7 +9,7 @@ import { checkStatus } from './checkStatus';
9 9 import { useGlobSetting } from '@/hooks/external/setting';
10 10 import { RequestEnum, ContentTypeEnum } from '@/enums/external/httpEnum';
11 11 import { isString } from '@/utils/external/is';
12   -import { getJwtToken } from '@/utils/external/auth';
  12 +import { getJwtToken, getShareJwtToken } from '@/utils/external/auth';
13 13 import { setObjToUrlParams, deepMerge } from '@/utils/external';
14 14 import { joinTimestamp, formatRequestDate } from './helper';
15 15 import { PageEnum } from '@/enums/external/pageEnum';
... ... @@ -89,14 +89,25 @@ const transform: AxiosTransform = {
89 89 */
90 90 requestInterceptors: (config, options) => {
91 91 // 请求之前处理config
92   - const token = getJwtToken();
93   - if (token && (config as Recordable)?.requestOptions?.withToken !== false) {
94   - // jwt token
95   - config.headers!['X-Authorization'] = options.authenticationScheme
96   - ? `${options.authenticationScheme} ${token}`
97   - : token as string;
  92 + const { requestOptions } = config;
  93 + const { withShareToken } = requestOptions || {};
  94 + const { requestOptions: { withToken } = {} } = options;
  95 + if (withToken !== false) {
  96 + const shareToken = getShareJwtToken();
  97 + if (withShareToken && shareToken) {
  98 + config.headers!['X-Authorization'] = options.authenticationScheme
  99 + ? `${options.authenticationScheme} ${shareToken}`
  100 + : shareToken;
  101 + } else {
  102 + const token = getJwtToken();
  103 + if (token) {
  104 + config.headers!['X-Authorization'] = options.authenticationScheme
  105 + ? `${options.authenticationScheme} ${token}`
  106 + : token;
  107 + }
  108 + }
98 109 }
99   - return config;
  110 + return config
100 111 },
101 112
102 113 /**
... ...
  1 +export const isShareMode = () => {
  2 + const sharePageReg = /^\/share\/[^/]+\/[^/]+\/[^/]+$/;
  3 + const { hash } = location;
  4 + return sharePageReg.test(hash.substring(1));
  5 +};
... ...
... ... @@ -42,7 +42,7 @@ const getToken = async () => {
42 42 const { params } = ROUTE
43 43 const { publicId } = params as Record<'id' | 'publicId', string>
44 44 const { token, refreshToken } = await getPublicToken(publicId)
45   - userStore.storeToken(token, refreshToken)
  45 + userStore.storeShareToken(token, refreshToken)
46 46 }
47 47
48 48 const checkNeedAccessToken = async () => {
... ...
... ... @@ -20,7 +20,8 @@
20 20 ],
21 21 "typeRoots": [
22 22 "./node_modules/@types/",
23   - "./types"
  23 + "./types",
  24 + "./types/external"
24 25 ],
25 26 "paths": {
26 27 "@/*": [
... ...
... ... @@ -21,6 +21,8 @@ export interface RequestOptions {
21 21 ignoreCancelToken?: boolean;
22 22 // Whether to send token in header
23 23 withToken?: boolean;
  24 + // Carry and share token 携带分享的访问令牌
  25 + withShareToken?: boolean
24 26 }
25 27
26 28 export interface Result<T = any> {
... ...