MFA登录状态持久管理和页面优化
continuous-integration/drone/push Build is passing
Details
continuous-integration/drone/push Build is passing
Details
parent
0f6da34395
commit
02a5e2fdc2
|
|
@ -20,6 +20,7 @@
|
|||
"@cornerstonejs/core": "^2.19.7",
|
||||
"@cornerstonejs/dicom-image-loader": "^2.19.7",
|
||||
"@cornerstonejs/tools": "^2.19.7",
|
||||
"@fingerprintjs/fingerprintjs": "^4.6.2",
|
||||
"@icr/polyseg-wasm": "^0.4.0",
|
||||
"@microsoft/signalr": "^8.0.7",
|
||||
"@riophae/vue-treeselect": "^0.4.0",
|
||||
|
|
|
|||
|
|
@ -1,25 +1,11 @@
|
|||
<template>
|
||||
<!--MFA-->
|
||||
<el-dialog
|
||||
v-if="visible"
|
||||
:visible.sync="visible"
|
||||
width="540px"
|
||||
:close-on-click-modal="false"
|
||||
append-to-body
|
||||
center
|
||||
:show-close="status === 'login'"
|
||||
@close="cancel"
|
||||
>
|
||||
<el-dialog v-if="visible" :visible.sync="visible" width="540px" :close-on-click-modal="false" append-to-body center
|
||||
:show-close="status === 'login'" @close="cancel">
|
||||
<div slot="title">
|
||||
{{ status === "login" ? $t("mfa:title") : $t("mfa:lock:title") }}
|
||||
</div>
|
||||
<el-form
|
||||
ref="mfaForm"
|
||||
label-position="right"
|
||||
:model="form"
|
||||
:rules="rules"
|
||||
label-width="100px"
|
||||
>
|
||||
<el-form ref="mfaForm" label-position="right" :model="form" :rules="rules" label-width="100px">
|
||||
<!-- 邮箱 -->
|
||||
<p class="tip_mfa">
|
||||
<i class="el-icon-warning" style="color: #409eff"></i>
|
||||
|
|
@ -31,18 +17,11 @@
|
|||
</el-form-item>
|
||||
<!-- 验证码 -->
|
||||
<el-form-item :label="$t('mfa:form:MFACode')" prop="Code">
|
||||
<el-input
|
||||
:placeholder="$t('mfa:form:input:placeholder:Codes')"
|
||||
v-model="form.Code"
|
||||
style="width: 240px; margin-right: 10px"
|
||||
/>
|
||||
<el-button
|
||||
type="primary"
|
||||
size="small"
|
||||
@click.stop="sendMFACode"
|
||||
:disabled="flag || sendFlag"
|
||||
>{{ flag ? `${second}s` : $t("mfa:form:sendMFACode") }}</el-button
|
||||
>
|
||||
<el-input :placeholder="$t('mfa:form:input:placeholder:Codes')" v-model="form.Code"
|
||||
style="width: 200px; margin-right: 10px" />
|
||||
<el-button type="primary" size="small" @click.stop="sendMFACode" :disabled="flag || sendFlag"
|
||||
style="float: right;margin-right: 35px;">{{ flag ?
|
||||
`${second}s ${$t("mfa:form:sendMFACodeCountDown")}` : $t("mfa:form:sendMFACode") }}</el-button>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
<div slot="footer">
|
||||
|
|
@ -51,19 +30,16 @@
|
|||
{{ $t("mfa:button:cancel") }}
|
||||
</el-button> -->
|
||||
<!-- 保存 -->
|
||||
<el-button
|
||||
type="primary"
|
||||
size="small"
|
||||
@click="save"
|
||||
:loading="loading"
|
||||
style="width: 80%"
|
||||
>
|
||||
<el-button type="primary" size="small" @click="save" :loading="loading" style="width: 80%">
|
||||
{{
|
||||
status === "login"
|
||||
? $t("mfa:button:save")
|
||||
: $t("mfa:lock:button:save")
|
||||
}}
|
||||
</el-button>
|
||||
<p style="text-align: left;font-size: 14px;margin:10px auto;width: 80%;">
|
||||
<el-checkbox v-model="form.isRemember" /><span style="margin-left: 10px;">{{ $t("mfa:tip:noLogin") }}</span>
|
||||
</p>
|
||||
</div>
|
||||
</el-dialog>
|
||||
</template>
|
||||
|
|
@ -86,6 +62,7 @@ export default {
|
|||
IdentityUserId: null,
|
||||
EMail: null,
|
||||
username: null,
|
||||
isRemember: true
|
||||
},
|
||||
rules: {
|
||||
Code: [
|
||||
|
|
@ -112,6 +89,18 @@ export default {
|
|||
},
|
||||
};
|
||||
},
|
||||
mounted() {
|
||||
this.flag = true;
|
||||
this.second = 60;
|
||||
this.timer = setInterval(() => {
|
||||
this.second--;
|
||||
if (this.second <= 0) {
|
||||
this.flag = false;
|
||||
clearInterval(this.timer);
|
||||
this.timer = null;
|
||||
}
|
||||
}, 1000);
|
||||
},
|
||||
methods: {
|
||||
open(data) {
|
||||
let { UserId, status, username, EMail } = data;
|
||||
|
|
@ -198,10 +187,12 @@ export default {
|
|||
line-height: 30px;
|
||||
border-radius: 5px;
|
||||
background-color: #eee;
|
||||
|
||||
i {
|
||||
margin-right: 5px;
|
||||
}
|
||||
}
|
||||
|
||||
::v-deep .el-dialog__header {
|
||||
font-weight: bold;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,32 @@
|
|||
import FingerprintJS from '@fingerprintjs/fingerprintjs';
|
||||
|
||||
export const customAgent = () => {
|
||||
return new Promise(async resolve => {
|
||||
const fpPromise = await FingerprintJS.load({
|
||||
monitoring: false
|
||||
});
|
||||
const result = await fpPromise.get({
|
||||
products: ['fonts', 'screen', 'canvas'],
|
||||
extendedData: true,
|
||||
debug: false
|
||||
})
|
||||
// const filteredComponents = Object.fromEntries(
|
||||
// Object.entries(result.components)
|
||||
// .filter(([key, value]) => value.confidence > 0.5)
|
||||
// );
|
||||
|
||||
resolve({
|
||||
...result,
|
||||
});
|
||||
// fpPromise
|
||||
// .then(fp => fp.get({
|
||||
// products: ['fonts', 'screen', 'canvas'],
|
||||
// extendedData: true,
|
||||
// debug: true
|
||||
// }))
|
||||
// .then(result => {
|
||||
// // 自定义数据转换
|
||||
|
||||
// });
|
||||
});
|
||||
}
|
||||
|
|
@ -5,6 +5,7 @@ import router from '@/router'
|
|||
import WHITELIST from "./whiteList"
|
||||
import moment from 'moment-timezone';
|
||||
import { encryptConfig } from "@/utils/encrypt"
|
||||
import { customAgent } from './fingerprint'
|
||||
const ROUTER = require('@/router');
|
||||
axios.defaults.withCredentials = false
|
||||
const service = axios.create({
|
||||
|
|
@ -26,6 +27,8 @@ service.interceptors.request.use(
|
|||
var language = zzSessionStorage.getItem('lang')
|
||||
config.headers['Accept-Language'] = language === 'en' ? 'en-US,en;q=0.5' : 'zh-CN,zh;q=0.9'
|
||||
config.headers['TimeZoneId'] = moment.tz.guess()
|
||||
let fingerprint = await customAgent()
|
||||
config.headers['BrowserFingerprint'] = fingerprint.visitorId
|
||||
if (config.ENCRYPT) {
|
||||
try {
|
||||
config = await encryptConfig(config)
|
||||
|
|
|
|||
Loading…
Reference in New Issue