首页> 实战笔录 >PHP开发笔记 >ThinkPHP ThinkPHP
TP6实现前后端分离的图片验证码,验证码怎么以接口形式返回
作者:小萝卜 2024-04-17 【 TP6 】 浏览 1062
简介thinkphp6.1提供的验证码插件是基于session,对于前后端分离的项目,并不能直接使用,但是我们可以间接使用它,而不用重新写一个插件。
thinkphp6.1提供的验证码插件是基于session,对于前后端分离的项目,并不能直接使用,但是我们可以间接使用它,而不用重新写一个插件。
首先我们安装一下官网提供的验证码插件
composer require topthink/think-captcha
输出验证码
接下里看看控制器写的获取验证码的代码
//图片验证码
public function verify(){
$uniqid = uniqid(rand(00000,99999));
$rs = Captcha::create();
$base64_image = "data:image/png;base64," . base64_encode($rs->getData());
$key = session('captcha.key');
cache('loginCode_'.$uniqid,$key);
return $this->success(['uniqid'=>$uniqid,'image'=>$base64_image]);
}
正常情况下,你只需这样return Captcha::create(),就能在网页上看到验证码,但前面说了,这是前后端分离的项目,因此返回给前端需要两个东西:用于设置缓存的唯一标识和base64加密的图片。
接下来解释一下代码,为什么是这么写的
我看了一下源码,打开Captcha.php发现Captcha::create()返回的是一个Response对象
public function create(string $config = null, bool $api = false): Response
Response里面有个getData()就是获取内容的方法,因此base64_encode($rs->getData())就是获取验证码图片
另外我们从源码中的generate(),这个是生成验证码的方法,其中有这样的代码
//$key这里的$key是验证码字符
$hash = password_hash($key, PASSWORD_BCRYPT, ['cost' => 10]);
$this->session->set('captcha', [
'key' => $hash,
]);
把验证码字符进行加密,存储到session,因此这里使用session('captcha.key')获取到这个key值,然后我们把它存储到缓存中,而这个key是使用uniqid()方法生成的唯一标识
验证输入的验证码是否正确
还是先看看验证的代码
$data = $this->request->post();
$key = cache('loginCode_'.$data['uniqid']);
if($key && password_verify(mb_strtolower($data['code'], 'UTF-8'), $key)){
cache('loginCode_'.$data['uniqid'],null);
}else{
return $this->failure(199,'验证码错误');
}
首先前端需要提交uniqid和code这两个字段过来,第一步判断cache('loginCode_'.$data['uniqid'])是否存在,如果存在,就判断输入进来的验证码是否正确,这里用到password_verify(),很多人可能有疑问,为什么这么写?
答案还是在源码里面,还是打开Captcha.php,其中有个验证验证码是否正确的方法
/**
* 验证验证码是否正确
* @access public
* @param string $code 用户验证码
* @return bool 用户验证码是否正确
*/
public function check(string $code): bool
{
if (!$this->session->has('captcha')) {
return false;
}
//就是这三行代码
$key = $this->session->get('captcha.key');
$code = mb_strtolower($code, 'UTF-8');
$res = password_verify($code, $key);
if ($res) {
$this->session->delete('captcha');
}
return $res;
}
我们对应的修改:
//源码
$key = $this->session->get('captcha.key');
//我们的代码
$key = cache(ADMIN_LOGIN_VERIFY_.$data['uniqid']);
//源码
$code = mb_strtolower($code, 'UTF-8');
$res = password_verify($code, $key);
//我们的代码
password_verify(mb_strtolower($data['code'], 'UTF-8'), $key)
其实就是照搬过来,一个前后端分离的验证码就这么简单的实现了~
很赞哦! (1)