从 PHP 到 AI + Golang,程序员自救转型手记(二十七):管理员登录验证码开关

这是一个系列 Blog,作者将以一个 PHP 全栈工程师的身份,利用 AI 工具(claude code、codex、deepseek、豆包等):从零开始学习 golang 语言,并最终完成 ai-go-admin(github | gitee)开源项目的制作,全程记录分享。

在上一期,我们进行了 "icon 组件封装",本期将完成:管理员登录验证码开关

管理员登录验证码开关

管理员登录人机验证码有时候需要关闭,比如为了内网开发环境下的测试方便等,这里直接将需求描述给 CC:

bash 复制代码
@config/captcha.yaml 增加管理员登录的人机验证码开关配置项,前端登录前使用 GET 请求获取该配置,根据配置确定点选验证码是否弹出,服务端登录接口根据该配置决定是否进行验证码效验

● 所有修改已完成,编译通过。以下是变更总结:

  1. config/captcha.yaml --- 新增 enabled 配置项
yaml 复制代码
captcha:
    enabled: true   # ← 新增,是否启用人机验证码
  1. internal/infra/config/config.go --- CaptchaConfig 增加 Enabled 字段
go 复制代码
type CaptchaConfig struct {
    Enabled         bool         `mapstructure:"enabled"`  // ← 新增
    Elements        []string     `mapstructure:"elements"`
    // ...
}
  1. internal/service/admin/admin.go --- 登录时根据配置决定是否校验验证码
go 复制代码
if config.Get().Captcha.Enabled {
    if ok, err := captcha.Check(req.Captcha, true); !ok {
        return nil, fmt.Errorf("验证码错误:%w", err)
    }
}
  1. internal/handler/common/captcha.go --- 新增 GET /common/captcha/config 接口

返回 {"code":200, "data":{"enabled":true}},供前端查询验证码开关状态。

  1. web/src/api/common.ts --- 新增 getCaptchaConfig() API 函数

  2. web/src/views/admin/login.vue --- 登录流程改造

  • onMounted 时调用 GET /common/captcha/config 获取配置
    • onSubmit 时根据 captchaEnabled 决定:
      • 启用:弹出点选验证码(原流程不变)
      • 关闭:跳过验证码,直接提交登录(captcha 字段给空值)
    • 获取配置失败时默认启用验证码(安全兜底)

使用方式:将 config/captcha.yaml 中的 enabled 设为 false 即可关闭管理员登录的人机验证码。


先简单看了下输出,确实加了配置项,叫做 captcha.enabled,但我们的 config/captcha.yaml,是全局验证码配置文件,而本次增加的开关只是管理员登录接口的验证码开关,所以这个配置名有点太广泛了,这里的规划明显就需要全局观了,未来可能还会增加会员登录接口的验证码开关,或者商户登录接口的,当前又是在 config/captcha.yaml 文件,最合理的应该是建立一个类似 开关 的数组,其内再存放各个模块的具体开关状态,我连变量名都懒得取,将这段思路发给 AI 即可,这波稳了一手,先开 plan mode。

bash 复制代码
  # 各接口人机验证码开关
  switches:
    # 管理员登录接口
    admin_login: true

AI 取出来一个 switches.admin_login,看来它理解了我的意思,下面先检查目录结构改动,然后对代码逐行 review:

验证码配置获取接口位置错误

获取验证码配置的接口,它放在了单独的公共接口之中,而我希望的是放在 admin/login-cofig 之类的独立接口中,登录页请求一下就行了。

go 复制代码
// internal\handler\common\captcha.go 文件

// Config 返回验证码配置(供前端判断是否启用人机验证)
func (h *CaptchaHandler) Config(c *gin.Context) {
	response.Success(c, response.WithData(gin.H{
		"admin_login": config.Get().Captcha.Switches.AdminLogin,
	}))
}

AI 调整后:

go 复制代码
// internal\handler\admin\admin.go 文件

// GetLoginConfig 返回管理员登录页配置
func (h *AdminHandler) GetLoginConfig(c *gin.Context) {
	response.Success(c, response.WithData(gin.H{
		"admin_login": config.Get().Captcha.Switches.AdminLogin,
	}))
}

// 路由注册增加一行

group.GET("/login-config", h.GetLoginConfig)

缺少合理封装

前端需要根据验证码开关状态确定是否弹出人机验证码,AI是这样写的:

ts 复制代码
if (captchaEnabled.value) {
    clickCaptcha((data) => {
        submitLoading.value = true
        adminLogin({ ...loginForm, captcha: data })
            .then((res) => {
                adminInfo.dataFill(res.data.data, false)
                router.push('/admin')
            })
            .finally(() => {
                submitLoading.value = false
            })
    })
} else {
    submitLoading.value = true
    adminLogin({ ...loginForm, captcha: { key: '', clicks: [], renderedWidth: 0, renderedHeight: 0 } })
        .then((res) => {
            adminInfo.dataFill(res.data.data, false)
            router.push('/admin')
        })
        .finally(() => {
            submitLoading.value = false
        })
}

很明显大部分代码可复用,冗余严重,改为:

ts 复制代码
const doLogin = (captcha?: ClickRequest) => {
    submitLoading.value = true
    adminLogin({ ...loginForm, captcha })
        .then((res) => {
            adminInfo.dataFill(res.data.data, false)
            router.push('/admin')
        })
        .finally(() => {
            submitLoading.value = false
        })
}

if (captchaEnabled.value) {
    clickCaptcha((data) => doLogin(data))
} else {
    doLogin()
}
相关推荐
孔令飞6 分钟前
【OneX】OneX AI 工具安装、配置及功能介绍
云原生·go·ai编程
溪语流沙7 分钟前
【Web全栈进阶】监控与告警:线上系统的“体检报告”
前端·vue.js·python·fastapi
鬼手点金11 分钟前
单轮对话:最简单的 API 调用
java·服务器·前端·javascript·react.js·servlet·tomcat
小虎AI生活13 分钟前
用 GPT-6 三天做出手机游戏是什么体验?附零基础四步实操
aigc·ai编程
莪_幻尘18 分钟前
10000 个中国版 Codex 在路上:桌面 Agent 争夺执行入口,一篇理清
openai·ai编程
李航198319 分钟前
DeepDraw 网页版
人工智能·python·计算机视觉·ai·ai编程
Elcker35 分钟前
Ynuo Agent(依诺) 一 0.3.10 发布:研发透明化,抛弃许愿式编程
人工智能·agent·ai编程
码哥字节36 分钟前
用 MCP 把排障 Agent 接上生产库,4 分钟定位 OOM
agent·ai编程
9i编程1 小时前
低代码平台实测踩坑记录:从审核排序到历史数据,问题逐条清零
人工智能·openai·ai编程
燕落南枝1 小时前
CSS 字体样式:颜色、字体族、倾斜、加粗与装饰
前端·css