mirror of
https://github.com/certd/certd.git
synced 2026-04-24 12:27:25 +08:00
perf: 登录支持极验验证码
This commit is contained in:
@@ -0,0 +1,13 @@
|
||||
|
||||
CREATE TABLE "cd_addon" (
|
||||
"id" integer PRIMARY KEY AUTOINCREMENT NOT NULL,
|
||||
"user_id" integer NOT NULL,
|
||||
"name" varchar(100) NOT NULL,
|
||||
"type" varchar(100) NOT NULL,
|
||||
"addon_type" varchar(100) NOT NULL,
|
||||
"is_default" boolean NOT NULL DEFAULT (false),
|
||||
"is_system" boolean NOT NULL DEFAULT (false),
|
||||
"setting" text,
|
||||
"create_time" datetime NOT NULL DEFAULT (CURRENT_TIMESTAMP),
|
||||
"update_time" datetime NOT NULL DEFAULT (CURRENT_TIMESTAMP)
|
||||
);
|
||||
@@ -0,0 +1,83 @@
|
||||
import { ALL, Body, Controller, Inject, Post, Provide, Query } from "@midwayjs/core";
|
||||
import { AddonRequestHandleReq, AddonService, Constants } from "@certd/lib-server";
|
||||
import { AddonController } from "../../user/addon/addon-controller.js";
|
||||
|
||||
@Provide()
|
||||
@Controller('/api/sys/addon')
|
||||
export class SysAddonController extends AddonController {
|
||||
@Inject()
|
||||
service2: AddonService;
|
||||
|
||||
getService(): AddonService {
|
||||
return this.service2;
|
||||
}
|
||||
|
||||
getUserId() {
|
||||
// checkComm();
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Post('/page', { summary: 'sys:settings:view' })
|
||||
async page(@Body(ALL) body: any) {
|
||||
return await super.page(body);
|
||||
}
|
||||
|
||||
@Post('/list', { summary: 'sys:settings:view' })
|
||||
async list(@Body(ALL) body: any) {
|
||||
return await super.list(body);
|
||||
}
|
||||
|
||||
@Post('/add', { summary: 'sys:settings:edit' })
|
||||
async add(@Body(ALL) bean: any) {
|
||||
return await super.add(bean);
|
||||
}
|
||||
|
||||
@Post('/update', { summary: 'sys:settings:edit' })
|
||||
async update(@Body(ALL) bean: any) {
|
||||
return await super.update(bean);
|
||||
}
|
||||
@Post('/info', { summary: 'sys:settings:view' })
|
||||
async info(@Query('id') id: number) {
|
||||
return await super.info(id);
|
||||
}
|
||||
|
||||
@Post('/delete', { summary: 'sys:settings:edit' })
|
||||
async delete(@Query('id') id: number) {
|
||||
return await super.delete(id);
|
||||
}
|
||||
@Post('/define', { summary: Constants.per.authOnly })
|
||||
async define(@Query('type') type: string,@Query('addonType') addonType: string) {
|
||||
return await super.define(type,addonType);
|
||||
}
|
||||
|
||||
@Post('/getTypeDict', { summary: Constants.per.authOnly })
|
||||
async getTypeDict(@Query('addonType') addonType: string) {
|
||||
return await super.getTypeDict(addonType);
|
||||
}
|
||||
|
||||
@Post('/simpleInfo', { summary: Constants.per.authOnly })
|
||||
async simpleInfo(@Query('addonType') addonType: string,@Query('id') id: number) {
|
||||
return await super.simpleInfo(addonType,id);
|
||||
}
|
||||
|
||||
@Post('/getDefaultId', { summary: Constants.per.authOnly })
|
||||
async getDefaultId(@Query('addonType') addonType: string) {
|
||||
return await super.getDefaultId(addonType);
|
||||
}
|
||||
|
||||
@Post('/setDefault', { summary: Constants.per.authOnly })
|
||||
async setDefault(@Query('addonType') addonType: string,@Query('id') id: number) {
|
||||
return await super.setDefault(addonType,id);
|
||||
}
|
||||
|
||||
|
||||
@Post('/options', { summary: Constants.per.authOnly })
|
||||
async options(@Query('addonType') addonType: string) {
|
||||
return await super.options(addonType);
|
||||
}
|
||||
|
||||
@Post('/handle', { summary: Constants.per.authOnly })
|
||||
async handle(@Body(ALL) body: AddonRequestHandleReq) {
|
||||
return await super.handle(body);
|
||||
}
|
||||
}
|
||||
@@ -1,18 +1,17 @@
|
||||
import { ALL, Body, Controller, Inject, Post, Provide, Query } from '@midwayjs/core';
|
||||
import { ALL, Body, Controller, Inject, Post, Provide, Query } from "@midwayjs/core";
|
||||
import {
|
||||
AccessGetter,
|
||||
AddonDefine,
|
||||
AddonRequestHandleReq,
|
||||
AddonService,
|
||||
Constants,
|
||||
CrudController,
|
||||
newAddon,
|
||||
ValidateException
|
||||
} from "@certd/lib-server";
|
||||
import { AuthService } from '../../../modules/sys/authority/service/auth-service.js';
|
||||
import { checkPlus } from '@certd/plus-core';
|
||||
import { AddonService } from "@certd/lib-server";
|
||||
import { AddonDefine } from "@certd/lib-server";
|
||||
import { AccessRequestHandleReq, newAccess } from "@certd/pipeline";
|
||||
import { AuthService } from "../../../modules/sys/authority/service/auth-service.js";
|
||||
import { checkPlus } from "@certd/plus-core";
|
||||
import { http, logger, utils } from "@certd/basic";
|
||||
|
||||
/**
|
||||
* Addon
|
||||
*/
|
||||
|
||||
@@ -1,8 +1,10 @@
|
||||
import { ALL, Body, Controller, Inject, Post, Provide } from '@midwayjs/core';
|
||||
import { LoginService } from '../../../modules/login/service/login-service.js';
|
||||
import { BaseController, Constants, SysPublicSettings, SysSettingsService } from '@certd/lib-server';
|
||||
import { CodeService } from '../../../modules/basic/service/code-service.js';
|
||||
import { checkComm } from '@certd/plus-core';
|
||||
import { ALL, Body, Controller, Inject, Post, Provide } from "@midwayjs/core";
|
||||
import { LoginService } from "../../../modules/login/service/login-service.js";
|
||||
import { AddonService, BaseController, Constants, SysPublicSettings, SysSettingsService } from "@certd/lib-server";
|
||||
import { CodeService } from "../../../modules/basic/service/code-service.js";
|
||||
import { checkComm } from "@certd/plus-core";
|
||||
import { logger } from "@certd/basic";
|
||||
import { ICaptchaAddon } from "../../../plugins/plugin-captcha/api.js";
|
||||
|
||||
/**
|
||||
*/
|
||||
@@ -16,14 +18,16 @@ export class LoginController extends BaseController {
|
||||
|
||||
@Inject()
|
||||
sysSettingsService: SysSettingsService;
|
||||
@Inject()
|
||||
addonService: AddonService;
|
||||
|
||||
@Post('/login', { summary: Constants.per.guest })
|
||||
public async login(
|
||||
@Body(ALL)
|
||||
user: any
|
||||
body: any
|
||||
) {
|
||||
await this.loginService.doCaptchaValidate({form:user})
|
||||
const token = await this.loginService.loginByPassword(user);
|
||||
await this.loginService.doCaptchaValidate({form:body.captcha})
|
||||
const token = await this.loginService.loginByPassword(body);
|
||||
this.writeTokenCookie(token);
|
||||
return this.ok(token);
|
||||
}
|
||||
@@ -79,4 +83,24 @@ export class LoginController extends BaseController {
|
||||
});
|
||||
return this.ok();
|
||||
}
|
||||
|
||||
@Post('/captcha/getParams', { summary: Constants.per.guest })
|
||||
async getCaptchaParams() {
|
||||
|
||||
const settings = await this.sysSettingsService.getPublicSettings()
|
||||
if (settings.captchaEnabled) {
|
||||
const addonId = settings.captchaAddonId;
|
||||
|
||||
const addon:ICaptchaAddon = await this.addonService.getAddonById(addonId,true,0)
|
||||
if (!addon) {
|
||||
logger.warn('验证码插件还未配置')
|
||||
return this.ok({});
|
||||
}
|
||||
|
||||
const params = await addon.getClientParams()
|
||||
return this.ok(params);
|
||||
}
|
||||
|
||||
return this.ok({});
|
||||
}
|
||||
}
|
||||
|
||||
@@ -105,19 +105,21 @@ export class LoginService {
|
||||
const pubSetting = await this.sysSettingsService.getPublicSettings()
|
||||
|
||||
if (pubSetting.captchaEnabled) {
|
||||
const prvSetting = await this.sysSettingsService.getPrivateSettings()
|
||||
|
||||
const addon = await this.addonService.getById(prvSetting.captchaAddonId,0)
|
||||
const addon = await this.addonService.getById(pubSetting.captchaAddonId,0)
|
||||
if (!addon) {
|
||||
logger.warn('验证码插件还未配置,忽略验证码校验')
|
||||
return true
|
||||
}
|
||||
if (addon.addonType !== pubSetting.captchaType) {
|
||||
if (addon.define.name !== pubSetting.captchaType) {
|
||||
logger.warn('验证码插件类型错误,忽略验证码校验')
|
||||
return true
|
||||
}
|
||||
|
||||
return await addon.onValidate(opts.form)
|
||||
const res = await addon.onValidate(opts.form)
|
||||
if (!res) {
|
||||
throw new Error('验证码错误');
|
||||
}
|
||||
}
|
||||
|
||||
return true
|
||||
|
||||
@@ -0,0 +1,4 @@
|
||||
export interface ICaptchaAddon{
|
||||
onValidate(data?:any):Promise<any>;
|
||||
getClientParams():Promise<any>;
|
||||
}
|
||||
@@ -1,12 +1,13 @@
|
||||
import { AddonInput, BaseAddon, IsAddon } from "@certd/lib-server/dist/user/addon/api/index.js";
|
||||
import crypto from 'crypto';
|
||||
import { ICaptchaAddon } from "../api.js";
|
||||
@IsAddon({
|
||||
addonType:"captcha",
|
||||
name: 'geetest',
|
||||
title: '极验验证码',
|
||||
desc: '',
|
||||
})
|
||||
export class GeeTestCaptcha extends BaseAddon {
|
||||
export class GeeTestCaptcha extends BaseAddon implements ICaptchaAddon{
|
||||
@AddonInput({
|
||||
title: 'captchaId',
|
||||
component: {
|
||||
@@ -43,6 +44,9 @@ export class GeeTestCaptcha extends BaseAddon {
|
||||
var captcha_output = data['captcha_output'];
|
||||
var pass_token = data['pass_token'];
|
||||
var gen_time = data['gen_time'];
|
||||
if (!lot_number || !captcha_output || !pass_token || !gen_time) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// 生成签名, 使用标准的hmac算法,使用用户当前完成验证的流水号lot_number作为原始消息message,使用客户验证私钥作为key
|
||||
// 采用sha256散列算法将message和key进行单向散列生成最终的 “sign_token” 签名
|
||||
@@ -78,8 +82,6 @@ export class GeeTestCaptcha extends BaseAddon {
|
||||
this.ctx.logger.error("极验验证服务异常",e)
|
||||
return true
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
// 生成签名
|
||||
@@ -102,7 +104,13 @@ export class GeeTestCaptcha extends BaseAddon {
|
||||
timeout: 5000
|
||||
};
|
||||
const result = await this.ctx.http.request(options);
|
||||
return result.data;
|
||||
return result;
|
||||
}
|
||||
|
||||
async getClientParams(): Promise<any> {
|
||||
return {
|
||||
captchaId: this.captchaId,
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user