In the traditional Web development process, processing graphical verification codes is very simple. You only need to generate an image with a random string in the background and add the verification code content. Just put it into the Session. When the user submits the form, take out the judgment from Session[1].
But nowadays, API interaction and statelessness are increasingly respected. In the Session area, although the default configuration is not supported, there are still many ways to save the country.
In API development, we can also issue SessionID to the front end and achieve all this through PHP's built-in methods.
For example, we agreed with the previous paragraph that when the request containsX-Session-Id
and is not empty, it means that this session has already registered a SessionID. Otherwise, a SessionID will be issued and returned in the ResponseX-Session-Id
in the Header allows the previous section to record this SessionID. Let’s simply implement it below.
// code_session.php session_start(); // 这里假设已经通过 Header 获取到了 SessionID,并保存到了 $sessionId 变量中。 // 当 SessionID 不存在,或者 为空 则创建新的 SessionID 。 if(!isset($sessionId) || empty($sessionId)){ $sessionId = session_create_id(); // 因为前台还没有 SessionID ,所以下发一个,通知前端保存。 header('X-Session-Id: '.$sessionId); } // 设置当前会话的 SessionID 。 session_id($sessionId); // 这里我们就可以自由的读写 Session 了。 // 生成验证码 $code = mt_rand(1e3 ,1e4-1); // create_image 请自行实现 或者使用现有的图形验证码库生成。 $image = create_image($code); // 存储进去 Session $_SESSION['code'] = $code; // 输出一张图片 $image->output();
The above basically implements the generation of images. The front end only needs to addX-Session-ID
to the headers when submitting the form.
// code_session_validate.php session_start(); // 这里假设已经通过 Header 获取到了 SessionID,并保存到了 $sessionId 变量中。 // 当 SessionID 不存在,或者 为空 则创建新的 SessionID 。 if( !isset($sessionId) || empty($sessionId) || !isset($_POST['code']) || empty($_POST['code']) ){ // 因为没有提交 SessionID 过来 这个肯定就是不成立的了,所以直接终止即可。 exit; } // 设置当前会话的 SessionID 。 session_id($sessionId); if($_POST['code']!=$_SESSION['code']){ // 验证码错误啦 exit; } // 验证通过了就删掉 code, unset($_SESSION['code']);
Using Session above, we have basically implemented a simple verification, which is based on API interaction and does not rely on browser cookies. When we need something complex, such as sharing Session, these are beyond the scope of this article (in fact, it is now beyond the scope)
The next method is none Stateful, but requires the use of Redis. This is handled using the PHPRedis extension.
In most cases, we do not need to create too many Sessions like using Session above, resulting in some waste of resources. Of course, Session can do more than that. Let’s use Redis to do it below. Aclient actively issues
's image verification code.
The client generates a random string locally, and then splices it behind the address to obtain the verification code. The backend intercepts the random string generated by the client and uses it as a verification certificate. Enter Redis, and when submitting it to the client, you need to bring the previously generated random string for verification.
// code_client.php $salt = 'wertyujkdbaskndasda'; if(!isset($_GET['sign'])){ // 客户端没有提供签名,停止执行 exit; } // 用户传来的一切数据都是不可靠的,我们需要对其加盐后执行 md5 $sign = md5($_GET['sign'].$salt); // 拼接上签名作为 Redis 的 key $key = 'code:'.$sign; // 连接 Redis $cache = new \Redis(); // 生成验证码 $code = mt_rand(1e3,1e4-1); // 保存验证码到 Redis 并设置2分钟的有效期。 if($cache->exists($key)){ // 这个 Key 已经被占用了,这里先停止。 exit; } $cache->set($key,$code,60*2); // 创建图片并返回 $image = create_image($code); $image->output();
Okay, let’s verify it.
// code_client_validate.php $salt = 'wertyujkdbaskndasda'; if( !isset($_POST['sign']) || !isset($_POST['code']) // 没有提交验证码过来。 || !empty($_POST['code']) ){ // 客户端没有提供签名,停止执行 exit; } // 用户传来的一切数据都是不可靠的,我们需要对其加盐后执行 md5 $sign = md5($_POST['sign'].$salt); // 拼接上签名作为 Redis 的 key $key = 'code:'.$sign; // 连接 Redis $cache = new \Redis(); if(!$cache->exists($key)){ // 根本没有这个 key eixt; } if($cache->get($key)!=$_POST['code']){ // 验证码错误 } // 验证通过了就删除 $cache->del($key);
It looks like it is a little more complicated, and even Redis is used. Although it doesn’t look good, it also achieves what we want, but this is not a very good solution. Moreover, we also need to consider that the client string is not random enough. Next, we change the direction and switch to server-side issuance.
What I just described is based on the implementation of client-side issuance. Here is another idea, but in general, this is almost the same.
The same is true for signing a Sign, but this time it is signed by the server, and then the Sign is sent to the client through the Header. The client needs to get theimage resource# first. ##, note that what is returned here should be a legal binary stream, then take out the Sign from the header and display it to the user.
// code_server.php $cache = new \Redis(); $salt = 'wertyujkdbaskndasda'; function generateSign(){ global $cache,$salt; $sign = md5(mt_rand().$salt); // 拼接上签名作为 Redis 的 key $key = 'code:'.$sign; if($cache->exists($key)){ // 是的 你么有看错,就是如果生成的 Sign 已存在,就进行递归,直到生成出一个不存在的。 return generateSign(); } return $key; } // 连接 Redis $key = generateSign(); // 生成验证码 $code = mt_rand(1e3,1e4-1); // 保存验证码到 Redis 并设置2分钟的有效期。 $cache->set($key,$code,60*2); // 创建图片并返回 $image = create_image($code); // 哈哈 要剃掉前缀哟 header('X-Captcha-Sign: ' . str_replace('code:','',$key)); $image->output();
X- in the headers. Captcha-SignThen show it on the interface. Of course, you can directly base64 the result or directly use the binary stream to generate a bitmap display. We just need to be able to verify it. The verification method can be directly used above.
Access-Control-Expose-Headers in the response header - HTTP | MDN, otherwise ajax cannot obtain the customized response header. .
header('Access-Control-Expose-Headers: X-Captcha-Sign');
gregwar/captcha - Packagist.
The above are just some of my personal understandings. If you have a better solution, please share it.
Reference[Note 1] The Session mentioned in this article is a technical standard and has a certain concept but is different from what we often call the automatic transfer of Cookies through the browser. Here I just manually implement the transfer of SessionID. , but always maintain the literal translation semantics of Session "session".
For more PHP related technical articles, please visit thePHP Tutorialcolumn to learn!
The above is the detailed content of How to create image verification code in API interaction. For more information, please follow other related articles on the PHP Chinese website!