Go商城项目---验证码模块的整个工作流程

本文将详细梳理一下这个验证码模块在典型 Web 应用中的整个工作流程,从用户打开登录页面到后端验证的全过程。

参与者:

  • 用户 (User): 最终与系统交互的人。
  • 前端 (Frontend): 用户在浏览器中看到的界面(HTML, CSS, JavaScript)。
  • 后端 (Backend): 运行在服务器上的 Go Gin 应用程序。
    • LoginController (包含 CaptchaDoLogin 方法)
    • models/captcha.go (包含 MakeCaptchaVerifyCaptcha 函数)
    • base64Captcha

工作流程:

  1. 用户访问登录页面:

    • 用户在浏览器中输入登录页面的 URL,或者点击了指向登录页面的链接。
    • 后端(例如 LoginControllerIndex 方法)接收到这个请求,渲染并返回登录页面的 HTML 给浏览器。
      // controllers/admin/login.go
      func (con LoginController) Index(c *gin.Context) {
          c.HTML(http.StatusOK, "admin/login/login.html", gin.H{})
      }
      
    • 前端浏览器展示登录页面,通常包含用户名输入框、密码输入框、验证码输入框以及一个显示验证码图片的位置。
  2. 前端请求并显示验证码:

    • 时机: 登录页面加载完成后,或者用户点击“刷新验证码”按钮时。
    • 前端操作:
      • 前端 JavaScript 代码会向后端发送一个 GET 请求到获取验证码的API接口(例如 /admin/captcha,这个路由会指向 LoginControllerCaptcha 方法)。
      • 这个请求可能是通过 AJAX (Asynchronous JavaScript and XML) 或 Fetch API 发送的,这样可以不刷新整个登录页面就更新验证码。
    • 后端处理 (LoginController.Captcha):
      1. LoginController.Captcha 方法被调用。
      2. 它调用 models.MakeCaptcha() 函数。
      3. models.MakeCaptcha() 内部:
        • 配置验证码的参数(如大小、字符集、字体、背景色等)来创建一个 base64Captcha.DriverString 实例。
        • 将其转换为一个 base64Captcha.Driver 接口。
        • 创建一个 base64Captcha.NewCaptcha(driver, store) 实例,这里的 storebase64Captcha.DefaultMemStore(一个全局的内存存储)。
        • 调用验证码实例的 c.Generate() 方法。
        • c.Generate() 内部 (由 base64Captcha 库实现):
          • 生成一个唯一的 captchaId
          • 根据驱动的配置生成验证码的答案 (例如,随机的4个字符)。
          • 将这个 captchaId 和对应的 answer 存储到 store 中 (例如,store.Set(captchaId, answer))。
          • 根据驱动的配置和生成的答案,绘制验证码图片。
          • 将绘制的图片编码为 Base64 字符串 (b64s)。
          • 返回 captchaId, b64s, answer (虽然在 MakeCaptchaanswer 被忽略了,但库内部是处理了的) 和 error
        • models.MakeCaptcha() 返回 captchaId, b64serrorLoginController.Captcha
      4. LoginController.Captcha 将获取到的 captchaIdb64s (图片Base64串) 包装成一个 JSON 对象返回给前端。
        {
            "captchaId": "some_unique_id_string",
            "captchaImage": "data:image/png;base64,iVBORw0KGgoAAAANS..." // 很长的Base64字符串
        }
        
    • 前端接收并显示:
      • 前端 JavaScript 接收到这个 JSON 响应。
      • 它会将 captchaImage (Base64字符串) 设置为一个 <img> 标签的 src 属性,浏览器会自动解码并显示图片。
      • 同时,前端会将 captchaId 存储起来,通常是放在一个隐藏的 <input type="hidden" name="captchaId" value="some_unique_id_string"> 表单字段中。这样当用户提交表单时,这个ID会一起发送到后端。
  3. 用户填写表单并提交登录请求:

    • 用户在登录页面输入用户名、密码和看到的验证码字符。
    • 用户点击“登录”按钮。
    • 前端操作:
      • 浏览器将表单数据(包括用户名、密码、用户输入的验证码值,以及之前存储的隐藏的 captchaId)通过 HTTP POST 请求发送到后端的登录处理接口(例如 /admin/doLogin,这个路由会指向 LoginControllerDoLogin 方法)。
    • 后端处理 (LoginController.DoLogin):
      1. LoginController.DoLogin 方法被调用。
      2. 从POST请求的表单数据中获取 captchaId (隐藏字段的值) 和 verifyValue (用户输入的验证码字符)。
        captchaId := c.PostForm("captchaId")
        verifyValue := c.PostForm("verifyValue")
        
      3. 调用 models.VerifyCaptcha(captchaId, verifyValue) 函数进行验证。
      4. models.VerifyCaptcha() 内部:
        • 它会调用 store.Verify(captchaId, verifyValue, true)
        • store.Verify() 内部 (由 base64Captcha 库的 DefaultMemStore 实现):
          • 根据传入的 captchaId 从内存存储中查找之前存储的正确答案。
          • 如果找到了,就将用户输入的 verifyValue 与存储的正确答案进行比较(通常是不区分大小写的比较)。
          • 如果 clear 参数为 true (在这个例子中是 true),则无论验证成功与否,都会从存储中删除这个 captchaId 对应的条目,以防止验证码被重复使用。
          • 返回比较结果(true 为匹配,false 为不匹配)。
        • models.VerifyCaptcha()store.Verify() 的结果返回给 LoginController.DoLogin
      5. LoginController.DoLogin 根据 models.VerifyCaptcha 返回的 flag (true 或 false) 执行后续操作:
        • 如果 flagtrue (验证码正确):
          • 目前代码只是返回 "验证码验证成功"
          • 在完整的应用中,接下来会进行用户名和密码的校验。 如果用户名密码也正确,则会创建用户会话(Session),设置Cookie,并重定向到用户后台或返回成功信息。
        • 如果 flagfalse (验证码错误):
          • 返回 "验证码验证失败"
          • 前端通常会提示用户验证码错误,并可能需要用户重新获取并输入验证码。
  4. 后续 (如果验证码正确且用户名密码也正确):

    • 用户登录成功,可以访问受保护的资源。
    • 会话管理开始生效。

关键点和注意事项:

  • 验证码的一次性: VerifyCaptcha 中的 clear 参数设置为 true 非常重要,确保了每个验证码只能被尝试验证一次,增加了安全性。
  • 存储机制: 当前使用的是内存存储 (DefaultMemStore)。这意味着如果后端应用重启,所有未验证的验证码都会失效。对于分布式部署或需要更高持久性的场景,可以考虑使用 Redis、数据库等作为 store 的实现(base64Captcha 库支持自定义 Store 接口)。
  • 安全性:
    • 验证码本身是为了防止机器人自动提交表单。
    • 除了验证码,还应有其他安全措施,如防止暴力破解(限制尝试次数)、HTTPS传输等。
  • 前端体验:
    • 提供刷新验证码的功能。
    • 清晰地显示验证码图片。
    • 在验证失败时给出明确的提示。
  • 解耦: LoginController 负责处理HTTP请求和响应,models/captcha.go 封装了验证码生成和验证的核心逻辑,第三方库 base64Captcha 提供了底层的验证码实现。这种分层和解耦使得代码更易于维护和测试。

这个流程清晰地展示了从验证码的生成、显示到最终验证的完整闭环。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值