feat(admin): 串联WordPress自动认证

This commit is contained in:
sunlei 2026-05-17 16:45:19 +08:00
parent 46452a5117
commit 88310e0ee1
4 changed files with 112 additions and 1 deletions

View File

@ -16,6 +16,25 @@ export namespace AuthApi {
data: string;
status: number;
}
export interface WordpressAuthResult {
auth: {
nonce: string;
type: 'cookie';
};
user?: Record<string, any>;
}
}
interface ApiSuccessResponse<T> {
code: number;
data: T;
msg: string;
}
interface RawApiResponse<T> {
data: ApiSuccessResponse<T>;
status: number;
}
/**
@ -53,6 +72,36 @@ export async function logoutApi() {
);
}
/**
* WordPress
*/
export async function wordpressLoginApi() {
const response = await baseRequestClient.post<
RawApiResponse<AuthApi.WordpressAuthResult>
>(
'/wordpress/auth/login',
{},
{
withCredentials: true,
},
);
return response.data.data;
}
/**
* WordPress
*/
export async function wordpressLogoutApi() {
return baseRequestClient.post(
'/wordpress/auth/logout',
{},
{
withCredentials: true,
},
);
}
/**
*
*/

View File

@ -50,6 +50,7 @@ function createRequestClient(baseURL: string, options?: RequestClientOptions) {
const accessStore = useAccessStore();
const authStore = useAuthStore();
accessStore.setAccessToken(null);
accessStore.setWordpressAuth(null);
if (
preferences.app.loginExpiredMode === 'modal' &&
accessStore.isAccessChecked
@ -80,12 +81,18 @@ function createRequestClient(baseURL: string, options?: RequestClientOptions) {
fulfilled: async (config) => {
const accessStore = useAccessStore();
const token = formatToken(accessStore.accessToken);
const wordpressNonce = accessStore.wordpressAuth?.nonce;
if (token) {
config.headers.Authorization = token;
} else {
delete config.headers.Authorization;
}
if (wordpressNonce && `${config.url || ''}`.includes('/wordpress/')) {
config.headers['X-WP-Nonce'] = wordpressNonce;
} else {
delete config.headers['X-WP-Nonce'];
}
config.headers['Accept-Language'] = preferences.app.locale;
return config;
},

View File

@ -10,7 +10,14 @@ import { resetAllStores, useAccessStore, useUserStore } from '@vben/stores';
import { notification } from 'antdv-next';
import { defineStore } from 'pinia';
import { getAccessCodesApi, getUserInfoApi, loginApi, logoutApi } from '#/api';
import {
getAccessCodesApi,
getUserInfoApi,
loginApi,
logoutApi,
wordpressLoginApi,
wordpressLogoutApi,
} from '#/api';
import { $t } from '#/locales';
export const useAuthStore = defineStore('auth', () => {
@ -61,6 +68,13 @@ export const useAuthStore = defineStore('auth', () => {
url.searchParams.set('ktUserInfo', JSON.stringify(userStore.userInfo));
}
if (accessStore.wordpressAuth) {
url.searchParams.set(
'ktWordpressAuth',
JSON.stringify(accessStore.wordpressAuth),
);
}
return url.toString();
} catch {
return target;
@ -108,11 +122,16 @@ export const useAuthStore = defineStore('auth', () => {
fetchUserInfo(),
getAccessCodesApi(),
]);
const wordpressAuth = await wordpressLoginApi();
userInfo = fetchUserInfoResult;
userStore.setUserInfo(userInfo);
accessStore.setAccessCodes(accessCodes);
accessStore.setWordpressAuth({
...wordpressAuth.auth,
user: wordpressAuth.user,
});
if (accessStore.loginExpired) {
accessStore.setLoginExpired(false);
@ -132,6 +151,20 @@ export const useAuthStore = defineStore('auth', () => {
});
}
}
} catch (error) {
accessStore.setAccessToken(null);
accessStore.setAccessCodes([]);
accessStore.setWordpressAuth(null);
userStore.setUserInfo(null);
try {
await wordpressLogoutApi();
await logoutApi();
} catch {
// 不做任何处理
}
throw error;
} finally {
loginLoading.value = false;
}
@ -147,6 +180,12 @@ export const useAuthStore = defineStore('auth', () => {
if (isLoggingOut.value) return; // 正在登出中, 说明已进入循环, 直接返回.
isLoggingOut.value = true; // 设置 标识
try {
await wordpressLogoutApi();
} catch {
// 不做任何处理
}
try {
await logoutApi();
} catch {
@ -156,6 +195,7 @@ export const useAuthStore = defineStore('auth', () => {
resetAllStores();
accessStore.setLoginExpired(false);
accessStore.setWordpressAuth(null);
}
// 回登录页带上当前路由地址

View File

@ -6,6 +6,12 @@ import { acceptHMRUpdate, defineStore } from 'pinia';
type AccessToken = null | string;
interface WordpressAuthState {
nonce: string;
type: 'cookie';
user?: Record<string, any>;
}
interface AccessState {
/**
*
@ -43,6 +49,10 @@ interface AccessState {
* accessToken
*/
refreshToken: AccessToken;
/**
* WordPress WordPress cookie httpOnly cookie
*/
wordpressAuth: null | WordpressAuthState;
}
/**
@ -94,6 +104,9 @@ export const useAccessStore = defineStore('core-access', {
setRefreshToken(token: AccessToken) {
this.refreshToken = token;
},
setWordpressAuth(auth: null | WordpressAuthState) {
this.wordpressAuth = auth;
},
unlockScreen() {
this.isLockScreen = false;
this.lockScreenPassword = undefined;
@ -107,6 +120,7 @@ export const useAccessStore = defineStore('core-access', {
'accessCodes',
'isLockScreen',
'lockScreenPassword',
'wordpressAuth',
],
},
state: (): AccessState => ({
@ -119,6 +133,7 @@ export const useAccessStore = defineStore('core-access', {
lockScreenPassword: undefined,
loginExpired: false,
refreshToken: null,
wordpressAuth: null,
}),
});