问题抛出

首先,使用的是think-captcha 拓展包

composer require topthink/think-captcha

它是需要开启session才能使用的,当验证码显示时,它同时会在session中存一份验证码。

开发接口时,发现怎么都不正确,最后发现了问题所在,

我每次刷新vue登录页面时,服务端总是会重新生成session文件
在这里插入图片描述

单独访问验证码时,则一直都是同一个session文件,它不会生成新的文件
在这里插入图片描述

在这里插入图片描述

因此总结出结论:

vue的登录页面和显示验证码的请求两个session会话是独立的。

所以,解决方案是,用缓存,同时使用自己的验证码类,简洁一点,好处理一点。

用缓存的好处是可以提高接口的通用性,比如一些 app 可能是不使用session,cookie的

解决方案

1.定义两个接口

//验证码图形展示接口
Route::get('captcha/:id', '\app\adminapi\controller\LoginController@showCaptcha');
//验证码接口
Route::get('captcha', '\app\adminapi\controller\LoginController@captcha');

2.控制器中实现方法
Captcha类是用的网上随便找的一个验证码类,我给它封装到composer包里面去了。

composer require x852/think-captcha
    public function showCaptcha($id)
    {

        $captcha = new Captcha();
        //存缓存,时间短一点,减少压力
        cache('captcha_' . $id, $captcha->getCode(),60);
        return $captcha->outImg();

    }


    public function captcha()
    {
        //验证码唯一标识
        $uniqid = uniqid((string)mt_rand(100000, 999999));
        $src = (string)\think\facade\Route::buildUrl('/captcha/' . $uniqid)->domain(true);
        $data = [
            'src' => $src,
            'uniqid' => $uniqid,
        ];
        return ok($data);
    }

前端请求验证码接口会返回如下

{
	"code": 200,
	"msg": "",
	"data": {
		"src": "http://adminapi.ns-shop.com/captcha/42734462375696bf8a5.html",
		"uniqid": "42734462375696bf8a5"
	}
}

然后前端把src赋值给img的src即可
在这里插入图片描述

登录接口 就需要提供 code 和 uniqid两个参数,进行验证

在这里插入图片描述

验证思路
从缓存中根据uniqid取出缓存中的值,然后和code 做对比,如果相同则验证通过,不同则验证失败,给出提示。

产生的问题

这种方式好处虽然很多,但是依然有问题,假如用户一直在刷新页面,那么会一直生成缓存,所以,我把缓存周期设置的很短,只设置为60秒

解决产生问题的备用思路

但是依然可以使用session的原理进行处理,那就是在前端在本地生成一个cookie然后请求的时候携带这个cookie,注意,这是是跨域携带cookie,这样服务端也能根据这个cookie识别唯一的客户端,然后用cookie的值当作缓存的key来进行验证码的更新操作,原理是这样,但是我没有实验过。

参考地址:

https://segmentfault.com/q/1010000009724669?utm_source=sf-similar-question
https://segmentfault.com/q/1010000016540741?utm_source=tag-newest
在这里插入图片描述

Logo

前往低代码交流专区

更多推荐