ThinkPHP图形验证码跨域问题,废弃Session,使用Cache缓存

ThinkPHP图形验证码跨域问题,废弃Session,使用Cache缓存


技术交流群:699951342

问题由来

我的web项目架构:Angular + ThinkPHP5,我采用了前后端分离模式,考虑项目拓展性,使用token而不使用Session。

现有解决方案

那么图形验证码的逻辑该如何设计,我搜集了许多方法:

技术 优点 缺点 逻辑 评价 相关网站
redis 高速缓存,提高后端响应速度 需要安装redis 生成验证码1234,将其保存到redis,使用后销毁 若你开发的系统已经使用到了redis,可以考虑此方法。 点击进入.
加密验证码 想的美 掩耳盗铃 返回给客户端【验证码图片】+【根据验证码加密的字符串】,用户提交【验证码】和【根据验证码加密的字符串】,若后端根据【验证码】加密出的【字符串】与【用户提交的字符串】吻合,则通过。 这是不可行的,验证码无法失效,客户端可以始终提交一个正确的【验证码】和【加密字符串】。 点击进入.

除此之外,验证码存数据库的解决方法可以归为第一类,redis也是数据库的一种。

我的方案

问题的根本在于如何让验证码使用后失效,也就是让验证码具有状态。
绞尽脑汁的我想通了:仅凭借逻辑代码无法让其具有状态。
我选择了ThinkPHP自带的Cache缓存,按道理说Cache缓存的实现也是一种键值数据库,Cache缓存通过写文件来实现数据库功能,虽然不如Redis读写内存响应速度快,但对图形验证码来说,足以。

改写底层逻辑

因为ThinkPHP的Captcha扩展基于Session,所以我改写了它。(没安装的请先按官网教程安装)
路径:vendor\topthink\think-captcha\src\Captcha.php
代码19行$config中的内容我做了修改,你可以安装你的偏好修改

如果你想使用自定义字体,请上传两份同样的ttf字体文件到think-captcha\assets下的ttfszhttfs文件夹下

<?php
// +----------------------------------------------------------------------
// | ThinkPHP [ WE CAN DO IT JUST THINK ]
// +----------------------------------------------------------------------
// | Copyright (c) 2006-2015 http://thinkphp.cn All rights reserved.
// +----------------------------------------------------------------------
// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )
// +----------------------------------------------------------------------
// | Author: sa<admin@mail.saylimo.com>
// +----------------------------------------------------------------------

namespace think\captcha;

use think\Cache;

class Captcha
{
   
    
    protected $config = [
        'seKey'    => 'ThinkPHP.CN',
        // 验证码加密密钥
        'codeSet'  => '2345678abcdefhijkmnpqrstuvwxyzABCDEFGHJKLMNPQRTUVWXY',
        // 验证码字符集合
        'expire'   => 1800,
        // 验证码过期时间(s)
        'useZh'    => false,
        // 使用中文验证码
        'zhSet'    => '们惊顿挤秒悬姆烂森糖圣凹陶词借',
        // 中文验证码字符串
        'useImgBg' => false,
        // 使用背景图片
        'fontSize' => 25,
        // 验证码字体大小(px)
        'useCurve' => true,
        // 是否画混淆曲线
        'useNoise' => true,
        // 是否添加杂点
        'imageH'   => 0,
        // 验证码图片高度
        'imageW'   => 0,
        // 验证码图片宽度
        'length'   => 4,
        // 验证码位数
        'fontttf'  => '',
        // 验证码字体,不设置随机获取
        'bg'       => [255,255,255],
        // 背景颜色
        'reset'    => true,
        // 验证成功后是否重置
    ];

    private $_image = null; // 验证码图片实例
    private $_color = null; // 验证码字体颜色

    /**
     * 架构方法 设置参数
     * @access public
     * @param  array $config 配置参数
     */
    public function __construct($config = [])
    {
   
        $this->config = array_merge($this->config, $config);
    }

    /**
     * 使用 $this->name 获取配置
     * @access public
     * @param  string $name 配置名称
     * @return mixed    配置值
     */
    public function __get($name)
    {
   
        return $this->config[$name];
    }

    /**
     * 设置验证码配置
     * @access public
     * @param  string $name  配置名称
     * @param  string $value 配置值
     * @return void
     */
    public function __set($name, $value)
    {
   
        if (isset($this->config[$name])) {
   
            $this->config[$name] = $value;
        }
    }

    /**
     * 检查配置
     * @access public
     * @param  string $name 配置名称
     * @return bool
     */
    public function __isset($name)
    {
   
        return isset($this->config[$name]);
    }

    /**
     * 验证验证码是否正确
     * @access public
     * @param string $code 用户验证码
     * @param string $id   验证码标识
     * @return bool 用户验证码是否正确
     */
    public function check($code, $id = '')
    {
   
        if (empty($code) || empty($id)) {
   
            return false;
        }
        if($this->authcode(strtoupper($code)) == Cache::get($id)){
   
            $this->reset && Cache::rm($id);
            return true;
        }
        return false;
    }

    /**
     * 输出验证码并把验证码的值保存的session中
     * 验证码保存到session的格式为: array('verify_code' => '验证码值', 'verify_time' => '验证码创建时间');
     * @access public
     * @param string $id 要生成验证码的标识
     * @return \think\Response
     */
    public function 
  • 3
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值