♻️ refactored login-related code
This commit is contained in:
@@ -1,18 +0,0 @@
|
|||||||
import {service} from "@/utils/alova/service.ts";
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 获取Gitee登录链接
|
|
||||||
*/
|
|
||||||
export const getGiteeUrl = () => {
|
|
||||||
return service.Get('/api/oauth/gitee/url',
|
|
||||||
{
|
|
||||||
meta: {
|
|
||||||
ignoreToken: true,
|
|
||||||
},
|
|
||||||
cacheFor: {
|
|
||||||
mode: "restore",
|
|
||||||
expire: 1000 * 60 * 60 * 24
|
|
||||||
}
|
|
||||||
}
|
|
||||||
);
|
|
||||||
};
|
|
@@ -1,21 +0,0 @@
|
|||||||
import {service} from "@/utils/alova/service.ts";
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get Github OAuth URL
|
|
||||||
*/
|
|
||||||
export const getGithubUrl = (state: string) => {
|
|
||||||
return service.Get('/api/oauth/github/url',
|
|
||||||
{
|
|
||||||
params: {
|
|
||||||
state: state
|
|
||||||
},
|
|
||||||
meta: {
|
|
||||||
ignoreToken: true,
|
|
||||||
},
|
|
||||||
cacheFor: {
|
|
||||||
mode: "restore",
|
|
||||||
expire: 1000 * 60 * 60 * 24
|
|
||||||
}
|
|
||||||
}
|
|
||||||
);
|
|
||||||
};
|
|
57
src/api/oauth/index.ts
Normal file
57
src/api/oauth/index.ts
Normal file
@@ -0,0 +1,57 @@
|
|||||||
|
import {service} from "@/utils/alova/service.ts";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取Gitee登录链接
|
||||||
|
*/
|
||||||
|
export const getGiteeUrl = () => {
|
||||||
|
return service.Get('/api/oauth/gitee/url',
|
||||||
|
{
|
||||||
|
meta: {
|
||||||
|
ignoreToken: true,
|
||||||
|
},
|
||||||
|
cacheFor: {
|
||||||
|
mode: "restore",
|
||||||
|
expire: 1000 * 60 * 60 * 24
|
||||||
|
}
|
||||||
|
}
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get Github OAuth URL
|
||||||
|
*/
|
||||||
|
export const getGithubUrl = (state: string) => {
|
||||||
|
return service.Get('/api/oauth/github/url',
|
||||||
|
{
|
||||||
|
params: {
|
||||||
|
state: state
|
||||||
|
},
|
||||||
|
meta: {
|
||||||
|
ignoreToken: true,
|
||||||
|
},
|
||||||
|
cacheFor: {
|
||||||
|
mode: "restore",
|
||||||
|
expire: 1000 * 60 * 60 * 24
|
||||||
|
}
|
||||||
|
}
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
export const getQQUrl = (state: string) => {
|
||||||
|
return service.Get('/api/oauth/qq/url',
|
||||||
|
{
|
||||||
|
params: {
|
||||||
|
state: state
|
||||||
|
},
|
||||||
|
meta: {
|
||||||
|
ignoreToken: true,
|
||||||
|
},
|
||||||
|
cacheFor: {
|
||||||
|
mode: "restore",
|
||||||
|
expire: 1000 * 60 * 60 * 24
|
||||||
|
}
|
||||||
|
}
|
||||||
|
);
|
||||||
|
};
|
@@ -1,18 +0,0 @@
|
|||||||
import {service} from "@/utils/alova/service.ts";
|
|
||||||
|
|
||||||
export const getQQUrl = (state: string) => {
|
|
||||||
return service.Get('/api/oauth/qq/url',
|
|
||||||
{
|
|
||||||
params: {
|
|
||||||
state: state
|
|
||||||
},
|
|
||||||
meta: {
|
|
||||||
ignoreToken: true,
|
|
||||||
},
|
|
||||||
cacheFor: {
|
|
||||||
mode: "restore",
|
|
||||||
expire: 1000 * 60 * 60 * 24
|
|
||||||
}
|
|
||||||
}
|
|
||||||
);
|
|
||||||
};
|
|
@@ -1,20 +0,0 @@
|
|||||||
import {service} from "@/utils/alova/service.ts";
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 获取临时二维码
|
|
||||||
* @param clientId
|
|
||||||
*/
|
|
||||||
export const generateQrCode = (clientId: string) => {
|
|
||||||
return service.Get('/api/oauth/wechat/qrcode',
|
|
||||||
{
|
|
||||||
params: {
|
|
||||||
client_id: clientId
|
|
||||||
},
|
|
||||||
cacheFor: null,
|
|
||||||
meta: {
|
|
||||||
ignoreToken: true,
|
|
||||||
},
|
|
||||||
}
|
|
||||||
);
|
|
||||||
};
|
|
||||||
|
|
@@ -1,5 +1,5 @@
|
|||||||
import {service} from "@/utils/alova/service.ts";
|
import {service} from "@/utils/alova/service.ts";
|
||||||
import {AccountLogin, PhoneLogin, ResetPassword} from "@/types/user";
|
import {AccountLogin, PhoneLogin, ResetPassword, WechatOffiaccountLogin} from "@/types/user";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 刷新token
|
* 刷新token
|
||||||
@@ -8,7 +8,7 @@ export const refreshToken = () => {
|
|||||||
return service.Post('/api/auth/token/refresh', {}, {
|
return service.Post('/api/auth/token/refresh', {}, {
|
||||||
meta: {
|
meta: {
|
||||||
authRole: 'refreshToken',
|
authRole: 'refreshToken',
|
||||||
ignoreToken: true,
|
ignoreToken: false,
|
||||||
signature: true
|
signature: true
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
@@ -89,16 +89,14 @@ export const resetPasswordApi = (param: ResetPassword) => {
|
|||||||
}
|
}
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 获取用户设备信息
|
* 微信扫码登录
|
||||||
* @param access_token
|
* @param param
|
||||||
*/
|
*/
|
||||||
export const getUserDevice = (access_token: string) => {
|
export const wechatOffiaccountLoginApi = (param: WechatOffiaccountLogin) => {
|
||||||
return service.Post('/api/user/device',
|
return service.Post('/api/user/wechat/offiaccount/login', {
|
||||||
{
|
openid: param.openid,
|
||||||
access_token: access_token,
|
client_id: param.client_id,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
meta: {
|
meta: {
|
||||||
@@ -108,3 +106,21 @@ export const getUserDevice = (access_token: string) => {
|
|||||||
}
|
}
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取临时二维码
|
||||||
|
* @param clientId
|
||||||
|
*/
|
||||||
|
export const generateQrCode = (clientId: string) => {
|
||||||
|
return service.Post('/api/user/wechat/offiaccount/qrcode', {
|
||||||
|
client_id: clientId
|
||||||
|
}, {
|
||||||
|
cacheFor: 60 * 60 * 24,
|
||||||
|
meta: {
|
||||||
|
ignoreToken: true,
|
||||||
|
signature: true
|
||||||
|
},
|
||||||
|
}
|
||||||
|
);
|
||||||
|
};
|
||||||
|
@@ -29,7 +29,7 @@ const router: Router = createRouter({
|
|||||||
router.beforeEach((to, _from, next) => {
|
router.beforeEach((to, _from, next) => {
|
||||||
// start();
|
// start();
|
||||||
const user = useStore().user;
|
const user = useStore().user;
|
||||||
const token: string | undefined = user.user.access_token;
|
const token: string | undefined = user.token;
|
||||||
const userId: string | undefined = user.user.uid;
|
const userId: string | undefined = user.user.uid;
|
||||||
|
|
||||||
// 检查用户是否已登录
|
// 检查用户是否已登录
|
||||||
|
@@ -1,24 +1,20 @@
|
|||||||
import {defineStore} from 'pinia';
|
import {defineStore} from 'pinia';
|
||||||
import {reactive} from 'vue';
|
|
||||||
import {generateClientId} from "@/api/client";
|
import {generateClientId} from "@/api/client";
|
||||||
import {getGithubUrl} from "@/api/oauth/github.ts";
|
|
||||||
import {getQQUrl} from "@/api/oauth/qq.ts";
|
|
||||||
import {getGiteeUrl} from "@/api/oauth/gitee.ts";
|
|
||||||
import {getUserDevice} from "@/api/user";
|
|
||||||
import {message} from "ant-design-vue";
|
import {message} from "ant-design-vue";
|
||||||
import {useI18n} from "vue-i18n";
|
import {useI18n} from "vue-i18n";
|
||||||
|
import {getGiteeUrl, getGithubUrl, getQQUrl} from "@/api/oauth";
|
||||||
|
|
||||||
export const useAuthStore = defineStore(
|
export const useAuthStore = defineStore(
|
||||||
'user',
|
'user',
|
||||||
() => {
|
() => {
|
||||||
const user: any = reactive({
|
const user: any = reactive({
|
||||||
access_token: '',
|
|
||||||
uid: '',
|
uid: '',
|
||||||
username: '',
|
username: '',
|
||||||
nickname: '',
|
nickname: '',
|
||||||
avatar: '',
|
avatar: '',
|
||||||
status: '',
|
status: '',
|
||||||
});
|
});
|
||||||
|
const token: any = ref<string>('');
|
||||||
const clientId = ref<string>('');
|
const clientId = ref<string>('');
|
||||||
const githubRedirectUrl = ref<string>('');
|
const githubRedirectUrl = ref<string>('');
|
||||||
const giteeRedirectUrl = ref<string>('');
|
const giteeRedirectUrl = ref<string>('');
|
||||||
@@ -74,14 +70,13 @@ export const useAuthStore = defineStore(
|
|||||||
if (typeof e.data === 'string') {
|
if (typeof e.data === 'string') {
|
||||||
const res: any = JSON.parse(e.data);
|
const res: any = JSON.parse(e.data);
|
||||||
if (res && res.code === 200) {
|
if (res && res.code === 200) {
|
||||||
const {data} = res;
|
const {uid, access_token, username, avatar, nickname, status} = res.data;
|
||||||
user.uid = data.uid;
|
user.uid = uid;
|
||||||
user.access_token = data.access_token;
|
user.username = username;
|
||||||
user.username = data.username;
|
user.avatar = avatar;
|
||||||
user.avatar = data.avatar;
|
user.nickname = nickname;
|
||||||
user.nickname = data.nickname;
|
user.status = status;
|
||||||
user.status = data.status;
|
token.value = access_token;
|
||||||
await getUserDevice(data.access_token);
|
|
||||||
message.success(t('login.loginSuccess'));
|
message.success(t('login.loginSuccess'));
|
||||||
window.removeEventListener("message", messageHandler);
|
window.removeEventListener("message", messageHandler);
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
@@ -130,9 +125,19 @@ export const useAuthStore = defineStore(
|
|||||||
window.addEventListener("message", messageHandler);
|
window.addEventListener("message", messageHandler);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function clear() {
|
||||||
|
token.value = "";
|
||||||
|
user.avatar = "";
|
||||||
|
user.uid = "";
|
||||||
|
user.username = "";
|
||||||
|
user.nickname = "";
|
||||||
|
user.status = "";
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
return {
|
return {
|
||||||
user,
|
user,
|
||||||
|
token,
|
||||||
clientId,
|
clientId,
|
||||||
getGithubRedirectUrl,
|
getGithubRedirectUrl,
|
||||||
getGiteeRedirectUrl,
|
getGiteeRedirectUrl,
|
||||||
@@ -141,6 +146,7 @@ export const useAuthStore = defineStore(
|
|||||||
openGithubUrl,
|
openGithubUrl,
|
||||||
openGiteeUrl,
|
openGiteeUrl,
|
||||||
openQQUrl,
|
openQQUrl,
|
||||||
|
clear
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@@ -154,7 +160,7 @@ export const useAuthStore = defineStore(
|
|||||||
persist: true,
|
persist: true,
|
||||||
storage: localStorage,
|
storage: localStorage,
|
||||||
key: 'user',
|
key: 'user',
|
||||||
includePaths: ['user', "clientId", "githubRedirectUrl", "giteeRedirectUrl", "qqRedirectUrl"]
|
includePaths: ['user', 'token', "clientId"]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
5
src/types/user.d.ts
vendored
5
src/types/user.d.ts
vendored
@@ -18,3 +18,8 @@ export interface ResetPassword {
|
|||||||
password?: string;
|
password?: string;
|
||||||
repassword?: string;
|
repassword?: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export interface WechatOffiaccountLogin {
|
||||||
|
openid:string;
|
||||||
|
client_id:string;
|
||||||
|
}
|
||||||
|
@@ -28,7 +28,7 @@ const {onAuthRequired, onResponseRefreshToken} = createServerTokenAuthentication
|
|||||||
const user = useStore().user;
|
const user = useStore().user;
|
||||||
const res: any = await refreshToken();
|
const res: any = await refreshToken();
|
||||||
if (res && res.code === 200) {
|
if (res && res.code === 200) {
|
||||||
user.user.access_token = res.data;
|
user.token = res.data;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -46,7 +46,8 @@ export const service = createAlova({
|
|||||||
beforeRequest: onAuthRequired(async (method: any) => {
|
beforeRequest: onAuthRequired(async (method: any) => {
|
||||||
if (!method.meta?.ignoreToken) {
|
if (!method.meta?.ignoreToken) {
|
||||||
const user = useStore().user;
|
const user = useStore().user;
|
||||||
method.config.headers.Authorization = `${import.meta.env.VITE_APP_TOKEN_KEY} ${user.user.access_token}`;
|
method.config.headers.Authorization = `${import.meta.env.VITE_APP_TOKEN_KEY} ${user.token}`;
|
||||||
|
method.config.headers['X-UID'] = user.user.uid;
|
||||||
}
|
}
|
||||||
const lang = useStore().lang;
|
const lang = useStore().lang;
|
||||||
method.config.headers['Accept-Language'] = lang.lang || 'zh';
|
method.config.headers['Accept-Language'] = lang.lang || 'zh';
|
||||||
@@ -72,11 +73,9 @@ export const service = createAlova({
|
|||||||
}, 1000);
|
}, 1000);
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
return Promise.reject(response.data);
|
return Promise.reject();
|
||||||
}
|
}
|
||||||
return response.data;
|
return response.data;
|
||||||
|
|
||||||
|
|
||||||
},
|
},
|
||||||
onError:
|
onError:
|
||||||
(error: AxiosError, _method: any) => {
|
(error: AxiosError, _method: any) => {
|
||||||
|
@@ -53,7 +53,7 @@ export class WebSocketService {
|
|||||||
};
|
};
|
||||||
|
|
||||||
private handleMessage = (event: MessageEvent): void => {
|
private handleMessage = (event: MessageEvent): void => {
|
||||||
const {data} = event;
|
const data = JSON.parse(event.data);
|
||||||
if (this.callbacks.message) {
|
if (this.callbacks.message) {
|
||||||
this.callbacks.message.forEach((cb) => (cb as MessageCallback)(data));
|
this.callbacks.message.forEach((cb) => (cb as MessageCallback)(data));
|
||||||
}
|
}
|
||||||
|
@@ -374,11 +374,11 @@ async function phoneLoginSubmit() {
|
|||||||
const res: any = await phoneLoginApi(phoneLoginForm);
|
const res: any = await phoneLoginApi(phoneLoginForm);
|
||||||
if (res && res.code === 200) {
|
if (res && res.code === 200) {
|
||||||
userStore.user.uid = res.data.uid;
|
userStore.user.uid = res.data.uid;
|
||||||
userStore.user.access_token = res.data.access_token;
|
|
||||||
userStore.user.username = res.data.username;
|
userStore.user.username = res.data.username;
|
||||||
userStore.user.avatar = res.data.avatar;
|
userStore.user.avatar = res.data.avatar;
|
||||||
userStore.user.nickname = res.data.nickname;
|
userStore.user.nickname = res.data.nickname;
|
||||||
userStore.user.status = res.data.status;
|
userStore.user.status = res.data.status;
|
||||||
|
userStore.token = res.data.access_token;
|
||||||
message.success(t('login.loginSuccess'));
|
message.success(t('login.loginSuccess'));
|
||||||
loginLoading.value = false;
|
loginLoading.value = false;
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
@@ -461,11 +461,11 @@ async function checkAccountLoginCaptcha(angle: number) {
|
|||||||
const res: any = await accountLoginApi(params);
|
const res: any = await accountLoginApi(params);
|
||||||
if (res && res.code === 200) {
|
if (res && res.code === 200) {
|
||||||
userStore.user.uid = res.data.uid;
|
userStore.user.uid = res.data.uid;
|
||||||
userStore.user.access_token = res.data.access_token;
|
|
||||||
userStore.user.username = res.data.username;
|
userStore.user.username = res.data.username;
|
||||||
userStore.user.avatar = res.data.avatar;
|
userStore.user.avatar = res.data.avatar;
|
||||||
userStore.user.nickname = res.data.nickname;
|
userStore.user.nickname = res.data.nickname;
|
||||||
userStore.user.status = res.data.status;
|
userStore.user.status = res.data.status;
|
||||||
|
userStore.token = res.data.access_token;
|
||||||
message.success(t('login.loginSuccess'));
|
message.success(t('login.loginSuccess'));
|
||||||
loginLoading.value = false;
|
loginLoading.value = false;
|
||||||
showAccountRotateCaptcha.value = false;
|
showAccountRotateCaptcha.value = false;
|
||||||
|
@@ -21,7 +21,7 @@
|
|||||||
class="qrlogin-card-qr"
|
class="qrlogin-card-qr"
|
||||||
:size="280"
|
:size="280"
|
||||||
:error-level="'H'"
|
:error-level="'H'"
|
||||||
:status="status"
|
:status="qrStatus"
|
||||||
@refresh="getQrCode"
|
@refresh="getQrCode"
|
||||||
:value=qrcode
|
:value=qrcode
|
||||||
:icon="logo"
|
:icon="logo"
|
||||||
@@ -46,20 +46,20 @@ import {useI18n} from "vue-i18n";
|
|||||||
import BoxDog from "@/components/BoxDog/BoxDog.vue";
|
import BoxDog from "@/components/BoxDog/BoxDog.vue";
|
||||||
import QRLoginFooter from "@/views/QRLogin/QRLoginFooter.vue";
|
import QRLoginFooter from "@/views/QRLogin/QRLoginFooter.vue";
|
||||||
import {useRouter} from 'vue-router';
|
import {useRouter} from 'vue-router';
|
||||||
import {generateQrCode} from "@/api/oauth/wechat.ts";
|
|
||||||
import logo from "@/assets/svgs/logo-album.svg";
|
import logo from "@/assets/svgs/logo-album.svg";
|
||||||
|
|
||||||
import useStore from "@/store";
|
import useStore from "@/store";
|
||||||
import {message} from "ant-design-vue";
|
import {message} from "ant-design-vue";
|
||||||
import {getUserDevice} from "@/api/user";
|
|
||||||
import BackgroundAnimation from "@/components/BackgroundAnimation/BackgroundAnimation.vue";
|
import BackgroundAnimation from "@/components/BackgroundAnimation/BackgroundAnimation.vue";
|
||||||
|
import {generateQrCode, wechatOffiaccountLoginApi} from "@/api/user";
|
||||||
|
import {WechatOffiaccountLogin} from "@/types/user";
|
||||||
|
|
||||||
const {t} = useI18n();
|
const {t} = useI18n();
|
||||||
|
|
||||||
const router = useRouter();
|
const router = useRouter();
|
||||||
|
|
||||||
const qrcode = ref<string>('');
|
const qrcode = ref<string>('');
|
||||||
const status = ref<string>('loading');
|
const qrStatus = ref<string>('loading');
|
||||||
const websocket = useStore().websocket;
|
const websocket = useStore().websocket;
|
||||||
const userStore = useStore().user;
|
const userStore = useStore().user;
|
||||||
|
|
||||||
@@ -73,7 +73,7 @@ async function getQrCode() {
|
|||||||
qrcode.value = res.data;
|
qrcode.value = res.data;
|
||||||
await handleListenMessage();
|
await handleListenMessage();
|
||||||
} else {
|
} else {
|
||||||
status.value = 'expired';
|
qrStatus.value = 'expired';
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -92,15 +92,20 @@ async function handleListenMessage() {
|
|||||||
// 注册消息接收处理函数
|
// 注册消息接收处理函数
|
||||||
websocket.on('message', async (res: any) => {
|
websocket.on('message', async (res: any) => {
|
||||||
if (res && res.code === 200) {
|
if (res && res.code === 200) {
|
||||||
status.value = 'scanned';
|
qrStatus.value = 'scanned';
|
||||||
const {data} = res;
|
const {openid, client_id } = res.data;
|
||||||
userStore.user.uid = data.uid;
|
const param: WechatOffiaccountLogin = {
|
||||||
userStore.user.access_token = data.access_token;
|
openid: openid,
|
||||||
userStore.user.username = data.username;
|
client_id: client_id
|
||||||
userStore.user.avatar = data.avatar;
|
};
|
||||||
userStore.user.nickname = data.nickname;
|
const response: any = await wechatOffiaccountLoginApi(param);
|
||||||
userStore.user.status = data.status;
|
const {uid, access_token, username, avatar, nickname, status} = response.data;
|
||||||
await getUserDevice(data.access_token);
|
userStore.user.uid = uid;
|
||||||
|
userStore.user.username = username;
|
||||||
|
userStore.user.avatar = avatar;
|
||||||
|
userStore.user.nickname = nickname;
|
||||||
|
userStore.user.status = status;
|
||||||
|
userStore.token = access_token;
|
||||||
message.success(t('login.loginSuccess'));
|
message.success(t('login.loginSuccess'));
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
router.push('/main/photo/all');
|
router.push('/main/photo/all');
|
||||||
@@ -122,9 +127,9 @@ watch(
|
|||||||
() => websocket.readyState,
|
() => websocket.readyState,
|
||||||
(newStatus) => {
|
(newStatus) => {
|
||||||
if (newStatus === WebSocket.OPEN) {
|
if (newStatus === WebSocket.OPEN) {
|
||||||
status.value = 'active';
|
qrStatus.value = 'active';
|
||||||
} else {
|
} else {
|
||||||
status.value = 'expired';
|
qrStatus.value = 'expired';
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
@@ -29,7 +29,7 @@ const upscale = useStore().upscale;
|
|||||||
const img = new Image();
|
const img = new Image();
|
||||||
const wsOptions = {
|
const wsOptions = {
|
||||||
url: import.meta.env.VITE_FILE_SOCKET_URL + "?user_id=" + user.user.uid,
|
url: import.meta.env.VITE_FILE_SOCKET_URL + "?user_id=" + user.user.uid,
|
||||||
protocols: [user.user.access_token],
|
protocols: [user.token],
|
||||||
};
|
};
|
||||||
|
|
||||||
onMounted(() => {
|
onMounted(() => {
|
||||||
|
Reference in New Issue
Block a user