Преглед изворни кода

增加是否启用登录二次验证全局参数

zuohuaijun пре 3 година
родитељ
комит
5175ec327d

+ 4 - 4
Admin.NET/Admin.NET.Core/Admin.NET.Core.xml

@@ -192,9 +192,9 @@
             默认密码
             </summary>
         </member>
-        <member name="F:Admin.NET.Core.CommonConst.SysCaptcha">
+        <member name="F:Admin.NET.Core.CommonConst.SysSecondVer">
             <summary>
-            验证码开关
+            登录二次验证
             </summary>
         </member>
         <member name="F:Admin.NET.Core.CommonConst.SysOpLog">
@@ -3931,9 +3931,9 @@
             退出系统
             </summary>
         </member>
-        <member name="M:Admin.NET.Core.Service.SysAuthService.GetCaptchaFlag">
+        <member name="M:Admin.NET.Core.Service.SysAuthService.GetSecondVerFlag">
             <summary>
-            是否启用验证
+            是否启用二次验证
             </summary>
             <returns></returns>
         </member>

+ 2 - 2
Admin.NET/Admin.NET.Core/Const/CommonConst.cs

@@ -17,9 +17,9 @@ public class CommonConst
     public const string SysPassword = "sys_password";
 
     /// <summary>
-    /// 验证码开关
+    /// 登录二次验证
     /// </summary>
-    public const string SysCaptcha = "sys_captcha";
+    public const string SysSecondVer = "sys_second_ver";
 
     /// <summary>
     /// 开启操作日志

+ 1 - 1
Admin.NET/Admin.NET.Core/SeedData/SysConfigSeedData.cs

@@ -19,7 +19,7 @@ public class SysConfigSeedData : ISqlSugarEntitySeedData<SysConfig>
             new SysConfig{ Id=252885263003802, Name="Token过期时间", Code="sys_token_expire", Value="10080", SysFlag=YesNoEnum.Y, Remark="Token过期时间", Order=3, GroupCode="Default", CreateTime=DateTime.Parse("2022-02-10 00:00:00") },
             new SysConfig{ Id=252885263003803, Name="操作日志", Code="sys_oplog", Value="True", SysFlag=YesNoEnum.Y, Remark="开启操作日志", Order=4, GroupCode="Default", CreateTime=DateTime.Parse("2022-02-10 00:00:00") },
             new SysConfig{ Id=252885263003804, Name="单点登录", Code="sys_single_login", Value="True", SysFlag=YesNoEnum.Y, Remark="开启单点登录", Order=5, GroupCode="Default", CreateTime=DateTime.Parse("2022-02-10 00:00:00") },
-            new SysConfig{ Id=252885263003805, Name="验证码", Code="sys_captcha", Value="True", SysFlag=YesNoEnum.Y, Remark="开启验证码", Order=6, GroupCode="Default", CreateTime=DateTime.Parse("2022-02-10 00:00:00") },
+            new SysConfig{ Id=252885263003805, Name="登录二次验证", Code="sys_second_ver", Value="True", SysFlag=YesNoEnum.Y, Remark="登录二次验证", Order=6, GroupCode="Default", CreateTime=DateTime.Parse("2022-02-10 00:00:00") },
         };
     }
 }

+ 5 - 6
Admin.NET/Admin.NET.Core/Service/Auth/SysAuthService.cs

@@ -59,8 +59,7 @@ public class SysAuthService : IDynamicApiController, ITransient
         //var host = _httpContextAccessor.HttpContext.Request.Host;
 
         // 判断验证码
-        var captchaEnabled = await GetCaptchaFlag();
-        if (captchaEnabled && !_captcha.Validate(input.CodeId.ToString(), input.Code))
+        if (!_captcha.Validate(input.CodeId.ToString(), input.Code))
             throw Oops.Oh(ErrorCodeEnum.D0009);
 
         var encryptPasswod = MD5Encryption.Encrypt(input.Password);
@@ -189,15 +188,15 @@ public class SysAuthService : IDynamicApiController, ITransient
     }
 
     /// <summary>
-    /// 是否启用验证
+    /// 是否启用二次验证
     /// </summary>
     /// <returns></returns>
-    [HttpGet("/captchaFlag")]
+    [HttpGet("/secondVerFlag")]
     [AllowAnonymous]
     [SuppressMonitor]
-    public async Task<bool> GetCaptchaFlag()
+    public async Task<bool> GetSecondVerFlag()
     {
-        return await _sysConfigService.GetConfigValue<bool>(CommonConst.SysCaptcha);
+        return await _sysConfigService.GetConfigValue<bool>(CommonConst.SysSecondVer);
     }
 
     /// <summary>

+ 68 - 68
Web/src/api-services/apis/sys-auth-api.ts

@@ -30,42 +30,6 @@ export const SysAuthApiAxiosParamCreator = function (configuration?: Configurati
     return {
         /**
          * 
-         * @summary 是否启用验证码
-         * @param {*} [options] Override http request option.
-         * @throws {RequiredError}
-         */
-        captchaFlagGet: async (options: AxiosRequestConfig = {}): Promise<RequestArgs> => {
-            const localVarPath = `/captchaFlag`;
-            // use dummy base URL string because the URL constructor only accepts absolute URLs.
-            const localVarUrlObj = new URL(localVarPath, 'https://example.com');
-            let baseOptions;
-            if (configuration) {
-                baseOptions = configuration.baseOptions;
-            }
-            const localVarRequestOptions :AxiosRequestConfig = { method: 'GET', ...baseOptions, ...options};
-            const localVarHeaderParameter = {} as any;
-            const localVarQueryParameter = {} as any;
-
-            // authentication Bearer required
-
-            const query = new URLSearchParams(localVarUrlObj.search);
-            for (const key in localVarQueryParameter) {
-                query.set(key, localVarQueryParameter[key]);
-            }
-            for (const key in options.params) {
-                query.set(key, options.params[key]);
-            }
-            localVarUrlObj.search = (new URLSearchParams(query)).toString();
-            let headersFromBaseOptions = baseOptions && baseOptions.headers ? baseOptions.headers : {};
-            localVarRequestOptions.headers = {...localVarHeaderParameter, ...headersFromBaseOptions, ...options.headers};
-
-            return {
-                url: localVarUrlObj.pathname + localVarUrlObj.search + localVarUrlObj.hash,
-                options: localVarRequestOptions,
-            };
-        },
-        /**
-         * 
          * @summary 生成图片验证码
          * @param {*} [options] Override http request option.
          * @throws {RequiredError}
@@ -228,6 +192,42 @@ export const SysAuthApiAxiosParamCreator = function (configuration?: Configurati
         },
         /**
          * 
+         * @summary 是否启用二次验证
+         * @param {*} [options] Override http request option.
+         * @throws {RequiredError}
+         */
+        secondVerFlagGet: async (options: AxiosRequestConfig = {}): Promise<RequestArgs> => {
+            const localVarPath = `/secondVerFlag`;
+            // use dummy base URL string because the URL constructor only accepts absolute URLs.
+            const localVarUrlObj = new URL(localVarPath, 'https://example.com');
+            let baseOptions;
+            if (configuration) {
+                baseOptions = configuration.baseOptions;
+            }
+            const localVarRequestOptions :AxiosRequestConfig = { method: 'GET', ...baseOptions, ...options};
+            const localVarHeaderParameter = {} as any;
+            const localVarQueryParameter = {} as any;
+
+            // authentication Bearer required
+
+            const query = new URLSearchParams(localVarUrlObj.search);
+            for (const key in localVarQueryParameter) {
+                query.set(key, localVarQueryParameter[key]);
+            }
+            for (const key in options.params) {
+                query.set(key, options.params[key]);
+            }
+            localVarUrlObj.search = (new URLSearchParams(query)).toString();
+            let headersFromBaseOptions = baseOptions && baseOptions.headers ? baseOptions.headers : {};
+            localVarRequestOptions.headers = {...localVarHeaderParameter, ...headersFromBaseOptions, ...options.headers};
+
+            return {
+                url: localVarUrlObj.pathname + localVarUrlObj.search + localVarUrlObj.hash,
+                options: localVarRequestOptions,
+            };
+        },
+        /**
+         * 
          * @summary Swagger登录检查
          * @param {*} [options] Override http request option.
          * @throws {RequiredError}
@@ -359,19 +359,6 @@ export const SysAuthApiFp = function(configuration?: Configuration) {
     return {
         /**
          * 
-         * @summary 是否启用验证码
-         * @param {*} [options] Override http request option.
-         * @throws {RequiredError}
-         */
-        async captchaFlagGet(options?: AxiosRequestConfig): Promise<(axios?: AxiosInstance, basePath?: string) => Promise<AxiosResponse<AdminResultBoolean>>> {
-            const localVarAxiosArgs = await SysAuthApiAxiosParamCreator(configuration).captchaFlagGet(options);
-            return (axios: AxiosInstance = globalAxios, basePath: string = BASE_PATH) => {
-                const axiosRequestArgs :AxiosRequestConfig = {...localVarAxiosArgs.options, url: basePath + localVarAxiosArgs.url};
-                return axios.request(axiosRequestArgs);
-            };
-        },
-        /**
-         * 
          * @summary 生成图片验证码
          * @param {*} [options] Override http request option.
          * @throws {RequiredError}
@@ -426,6 +413,19 @@ export const SysAuthApiFp = function(configuration?: Configuration) {
         },
         /**
          * 
+         * @summary 是否启用二次验证
+         * @param {*} [options] Override http request option.
+         * @throws {RequiredError}
+         */
+        async secondVerFlagGet(options?: AxiosRequestConfig): Promise<(axios?: AxiosInstance, basePath?: string) => Promise<AxiosResponse<AdminResultBoolean>>> {
+            const localVarAxiosArgs = await SysAuthApiAxiosParamCreator(configuration).secondVerFlagGet(options);
+            return (axios: AxiosInstance = globalAxios, basePath: string = BASE_PATH) => {
+                const axiosRequestArgs :AxiosRequestConfig = {...localVarAxiosArgs.options, url: basePath + localVarAxiosArgs.url};
+                return axios.request(axiosRequestArgs);
+            };
+        },
+        /**
+         * 
          * @summary Swagger登录检查
          * @param {*} [options] Override http request option.
          * @throws {RequiredError}
@@ -476,15 +476,6 @@ export const SysAuthApiFactory = function (configuration?: Configuration, basePa
     return {
         /**
          * 
-         * @summary 是否启用验证码
-         * @param {*} [options] Override http request option.
-         * @throws {RequiredError}
-         */
-        async captchaFlagGet(options?: AxiosRequestConfig): Promise<AxiosResponse<AdminResultBoolean>> {
-            return SysAuthApiFp(configuration).captchaFlagGet(options).then((request) => request(axios, basePath));
-        },
-        /**
-         * 
          * @summary 生成图片验证码
          * @param {*} [options] Override http request option.
          * @throws {RequiredError}
@@ -523,6 +514,15 @@ export const SysAuthApiFactory = function (configuration?: Configuration, basePa
         },
         /**
          * 
+         * @summary 是否启用二次验证
+         * @param {*} [options] Override http request option.
+         * @throws {RequiredError}
+         */
+        async secondVerFlagGet(options?: AxiosRequestConfig): Promise<AxiosResponse<AdminResultBoolean>> {
+            return SysAuthApiFp(configuration).secondVerFlagGet(options).then((request) => request(axios, basePath));
+        },
+        /**
+         * 
          * @summary Swagger登录检查
          * @param {*} [options] Override http request option.
          * @throws {RequiredError}
@@ -562,16 +562,6 @@ export const SysAuthApiFactory = function (configuration?: Configuration, basePa
 export class SysAuthApi extends BaseAPI {
     /**
      * 
-     * @summary 是否启用验证码
-     * @param {*} [options] Override http request option.
-     * @throws {RequiredError}
-     * @memberof SysAuthApi
-     */
-    public async captchaFlagGet(options?: AxiosRequestConfig) : Promise<AxiosResponse<AdminResultBoolean>> {
-        return SysAuthApiFp(this.configuration).captchaFlagGet(options).then((request) => request(this.axios, this.basePath));
-    }
-    /**
-     * 
      * @summary 生成图片验证码
      * @param {*} [options] Override http request option.
      * @throws {RequiredError}
@@ -614,6 +604,16 @@ export class SysAuthApi extends BaseAPI {
     }
     /**
      * 
+     * @summary 是否启用二次验证
+     * @param {*} [options] Override http request option.
+     * @throws {RequiredError}
+     * @memberof SysAuthApi
+     */
+    public async secondVerFlagGet(options?: AxiosRequestConfig) : Promise<AxiosResponse<AdminResultBoolean>> {
+        return SysAuthApiFp(this.configuration).secondVerFlagGet(options).then((request) => request(this.axios, this.basePath));
+    }
+    /**
+     * 
      * @summary Swagger登录检查
      * @param {*} [options] Override http request option.
      * @throws {RequiredError}

+ 1 - 1
Web/src/stores/themeConfig.ts

@@ -19,7 +19,7 @@ export const useThemeConfig = defineStore('themeConfig', {
 			 * 全局主题
 			 */
 			// 默认 primary 主题颜色
-			primary: '#0052D9', // '#FF6A00',
+			primary: '#DE2910', // '#0052D9',
 			// 是否开启深色模式
 			isIsDark: false,
 

+ 1 - 2
Web/src/theme/element.scss

@@ -276,8 +276,7 @@
 .el-dialog__header {
 	margin-right: 0;
 	padding-top: 10px;
-	// border-bottom: 1px solid var(--el-color-primary-light-1);
-	background: var(--el-color-primary-light-1);
+	background: var(--el-color-primary);
 }
 .el-dialog__footer {
 	border-top: 1px dashed var(--el-color-primary-light-5);

+ 45 - 50
Web/src/views/login/component/account.vue

@@ -21,9 +21,9 @@
 				</template>
 			</el-input>
 		</el-form-item>
-		<el-form-item class="login-animation3" prop="captcha" v-show="captchaEnabled">
+		<el-form-item class="login-animation3" prop="captcha">
 			<el-col :span="15">
-				<el-input text maxlength="4" :placeholder="$t('message.account.accountPlaceholder3')" v-model="ruleForm.code" clearable autocomplete="off" @keyup.enter="openVerify">
+				<el-input text maxlength="4" :placeholder="$t('message.account.accountPlaceholder3')" v-model="ruleForm.code" clearable autocomplete="off">
 					<template #prefix>
 						<el-icon>
 							<ele-Position />
@@ -39,7 +39,7 @@
 			</el-col>
 		</el-form-item>
 		<el-form-item class="login-animation4">
-			<el-button type="primary" class="login-content-submit" round v-waves @click="openVerify" :loading="loading.signIn">
+			<el-button type="primary" class="login-content-submit" round v-waves @click="secondVerEnabled ? openRotateVerify() : onSignIn()" :loading="loading.signIn">
 				<span>{{ $t('message.account.accountBtnText') }}</span>
 			</el-button>
 		</el-form-item>
@@ -47,16 +47,16 @@
 	</el-form>
 
 	<div class="dialog-header">
-		<el-dialog v-model="verifyVisible" width="290px" center :show-close="false" :modal-append-to-body="false">
+		<el-dialog v-model="rotateVerifyVisible" width="290px" center :show-close="false" :modal-append-to-body="false">
 			<DragVerifyImgRotate
 				ref="dragRef"
-				:imgsrc="verifyImg"
-				v-model:isPassing="isPass"
+				:imgsrc="rotateVerifyImg"
+				v-model:isPassing="isPassRotate"
 				text="请按住滑块拖动"
 				successText="验证通过"
 				handlerIcon="fa fa-angle-double-right"
 				successIcon="fa fa-hand-peace-o"
-				@passcallback="passVerify"
+				@passcallback="passRotateVerify"
 			/>
 		</el-dialog>
 	</div>
@@ -105,17 +105,17 @@ export default defineComponent({
 			loading: {
 				signIn: false,
 			},
-			verifyVisible: false,
-			isPass: false,
-			verifyImg: verifyImg,
 			captchaImage: '',
-			captchaEnabled: true,
+			secondVerEnabled: true,
+			rotateVerifyVisible: false,
+			rotateVerifyImg: verifyImg,
+			isPassRotate: false,
 		});
 		onMounted(async () => {
-			// 是否开启验证码验证
-			var res1 = await getAPI(SysAuthApi).captchaFlagGet();
-			state.captchaEnabled = res1.data.result ?? true;
-			if (!state.captchaEnabled) return;
+			// 是否开启二次验证
+			var res1 = await getAPI(SysAuthApi).secondVerFlagGet();
+			state.secondVerEnabled = res1.data.result ?? true;
+
 			getCaptcha();
 		});
 		// 获取验证码
@@ -131,26 +131,28 @@ export default defineComponent({
 		});
 		// 登录
 		const onSignIn = async () => {
-			// 先清空Token缓存
-			clearTokens();
+			ruleFormRef.value.validate(async (valid: boolean) => {
+				if (!valid) return false;
 
-			const [err, res] = await feature(getAPI(SysAuthApi).loginPost(state.ruleForm));
-			if (err) {
-				getCaptcha(); // 重新获取验证码
-				return;
-			}
-			if (res?.data.result?.accessToken == undefined) {
-				getCaptcha(); // 重新获取验证码
-				ElMessage.error('登录失败,请检查账号!');
-				return;
-			}
+				clearTokens(); // 先清空Token缓存
 
-			state.loading.signIn = true;
-			Session.set('token', res.data.result?.accessToken); // 缓存token
-			// 添加完动态路由再进行router跳转,否则可能报错 No match found for location with path "/"
-			await initBackEndControlRoutes();
-			// 再执行 signInSuccess
-			signInSuccess();
+				const [err, res] = await feature(getAPI(SysAuthApi).loginPost(state.ruleForm));
+				if (err) {
+					getCaptcha(); // 重新获取验证码
+					return;
+				}
+				if (res?.data.result?.accessToken == undefined) {
+					getCaptcha(); // 重新获取验证码
+					ElMessage.error('登录失败,请检查账号!');
+					return;
+				}
+
+				state.loading.signIn = true;
+				Session.set('token', res.data.result?.accessToken); // 缓存token
+				// 添加完动态路由再进行router跳转,否则可能报错 No match found for location with path "/"
+				await initBackEndControlRoutes();
+				signInSuccess(); // 再执行 signInSuccess
+			});
 		};
 		// 登录成功后的跳转
 		const signInSuccess = () => {
@@ -173,30 +175,23 @@ export default defineComponent({
 			NextLoading.start();
 		};
 		// 打开旋转验证
-		const openVerify = () => {
-			ruleFormRef.value.validate((valid: boolean) => {
-				if (!valid) return false;
-
-				if (!state.captchaEnabled) {
-					passVerify();
-				} else {
-					state.verifyVisible = true;
-					state.isPass = false;
-					dragRef.value?.reset();
-				}
-			});
+		const openRotateVerify = () => {
+			state.rotateVerifyVisible = true;
+			state.isPassRotate = false;
+			dragRef.value?.reset();
 		};
 		// 通过旋转验证
-		const passVerify = () => {
-			state.verifyVisible = false;
-			state.isPass = true;
+		const passRotateVerify = () => {
+			state.rotateVerifyVisible = false;
+			state.isPassRotate = true;
 			onSignIn();
 		};
 		return {
 			ruleFormRef,
 			dragRef,
-			openVerify,
-			passVerify,
+			onSignIn,
+			openRotateVerify,
+			passRotateVerify,
 			getCaptcha,
 			...toRefs(state),
 		};

+ 1 - 1
Web/src/views/system/user/index.vue

@@ -43,7 +43,7 @@
 						</el-table-column>
 						<el-table-column label="性别" width="70" align="center" show-overflow-tooltip>
 							<template #default="scope">
-								<el-tag v-if="scope.row.sex === 1"> 男 </el-tag>
+								<el-tag type="success" v-if="scope.row.sex === 1"> 男 </el-tag>
 								<el-tag type="danger" v-else> 女 </el-tag>
 							</template>
 						</el-table-column>