Maison  >  Article  >  développement back-end  >  Comment créer un code de vérification d'image dans l'interaction API

Comment créer un code de vérification d'image dans l'interaction API

步履不停
步履不停original
2019-06-18 16:20:033283parcourir

Comment créer un code de vérification d'image dans l'interaction API

Avant-propos

Dans le processus de développement Web traditionnel, le traitement des codes de vérification graphiques est très simple. Il vous suffit de générer une image avec une chaîne aléatoire en arrière-plan et de l'ajouter. le contenu du code de vérification. Mettez-le simplement dans la session Lorsque l'utilisateur soumet le formulaire, retirez-le simplement de la session [1] et portez votre jugement.

Mais de nos jours, l'interaction API et l'apatridie sont de plus en plus respectées. En termes de session, bien que la configuration par défaut ne soit pas prise en charge, il existe encore de nombreuses façons de sauver le pays.

Implémentation basée sur la session

Dans le développement d'API, nous pouvons également émettre un SessionID au front-end et réaliser tout cela grâce aux méthodes intégrées de PHP.
Par exemple, nous sommes d'accord avec le paragraphe précédent que lorsque la requête contient X-Session-Id et n'est pas vide, cela signifie que cette session a déjà enregistré un SessionID. Sinon, un SessionID sera promulgué et le X-Session-Id dans le. L'en-tête de réponse sera renvoyé. Laissez le paragraphe précédent enregistrer cet ID de session et implémentez-le brièvement ci-dessous.

// 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();

Ce qui précède implémente essentiellement la génération d'images. Le front-end n'a besoin que d'ajouter X-Session-ID dans les en-têtes lors de la soumission du formulaire.

// 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']);

En utilisant la session ci-dessus, nous avons essentiellement implémenté une vérification simple, basée sur l'interaction API et ne repose pas sur les cookies du navigateur. Lorsque nous avons besoin de quelque chose de complexe, comme le partage de Session, cela dépasse le cadre de cet article (en fait, cela dépasse désormais le cadre)

Signature active basée sur le client

La suite La méthode n’a aucun état, mais nécessite l’utilisation de Redis. Ceci est géré à l’aide de l’extension PHPRedis.

Dans la plupart des cas, nous n'avons pas besoin de créer trop de sessions comme en utilisant Session ci-dessus, ce qui entraîne un certain gaspillage de ressources. Bien sûr, Session peut faire plus que cela. Utilisons Redis pour le faire ci-dessous. 客户端主动签发 code de vérification de l'image.

Principe théorique

Le client génère une chaîne aléatoire localement, puis la colle derrière l'adresse pour obtenir le code de vérification. Le backend intercepte la chaîne aléatoire générée par le client et l'utilise comme code de vérification. certificat de vérification. Entrez Redis et lorsque vous le soumettez au client, vous devez apporter la chaîne aléatoire générée précédemment pour vérification.

// 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();

D'accord, vérifions-le.

// 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);

On dirait que c'est un peu plus compliqué, et même Redis est utilisé. Même si cela n'a pas l'air bien, cela permet également d'obtenir ce que nous voulons, mais ce n'est pas une très bonne solution. Il faut également considérer que la chaîne client n'est pas assez aléatoire. Ensuite, nous changeons de direction et passons à l'émission côté serveur.

Basé sur l'émission côté serveur

L'implémentation actuelle est basée sur l'émission côté client. Ce qui suit fournira une autre idée, mais en général, c'est presque la même chose.

Principe théorique

Le signe est également émis, mais cette fois il est signé par le serveur, puis le signe est envoyé au client via l'en-tête. Le client doit d'abord obtenir le <.>ressource image, notez que ce qui est renvoyé ici doit être un flux binaire légal, puis le signe est retiré de l'en-tête et affiché à l'utilisateur.

// 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();

Il semble qu'il n'y ait presque aucun changement, sauf que la façon de générer Sign a changé. Cependant, si cela est fait, les étudiants front-end peuvent être mécontents. Ils doivent d'abord obtenir cette ressource et dans les en-têtes avant d'afficher Sur l'interface, bien sûr, vous pouvez directement base64 le résultat ou directement utiliser le flux binaire pour générer un bitmap à afficher. Il suffit de pouvoir le vérifier. La méthode de vérification peut être directement utilisée comme ci-dessus. .

X-Captcha-SignAttention particulière

Lorsque vous utilisez ajax pour obtenir cette ressource, si votre entreprise implique plusieurs domaines, vous devez également définir

Access-Control-Expose-Headers dans l'en-tête de réponse - HTTP | MDN

, sinon ajax ne peut pas obtenir l'en-tête de réponse personnalisé. .

header('Access-Control-Expose-Headers: X-Captcha-Sign');
Résumé

Après avoir examiné ces trois solutions, elles peuvent fondamentalement répondre à nos besoins. Quelqu'un a peut-être pensé à une autre solution. Fournissez un nom d'interface json, générez l'image en arrière-plan et enregistrez-la, renvoyez l'url et signez au front-end, c'est bien, mais de cette façon, nos ressources ne sont pas très contrôlables, et cela entraînera un certain gaspillage de ressources. Je n’en ai aucune idée ici.

Certaines des connaissances mentionnées dans l'article sont l'application de certaines connaissances de base. Le code dans l'article a été tapé directement lors de la rédaction de l'article. S'il y a des erreurs typographiques ou des erreurs logiques, n'hésitez pas à m'éclairer. .

Le Redis utilisé dans cet article est l'extension PHPRedis. Quant à la génération d'images de code de vérification, vous pouvez utiliser

gregwar/captcha - Packagist

.

Ce qui précède n'est que ma compréhension personnelle. Si vous avez une meilleure solution, partagez-la.

Référence

PHP : Sessions - Manuel

[Note 1] La Session mentionnée dans cet article est une norme technique et il existe un certain concept de Session dans l'interaction dont nous parlons souvent du passage automatique des cookies via le navigateur. Ici, j'implémente simplement le transfert de SessionID. , mais conservez toujours la sémantique de traduction littérale de Session "session".

Pour plus d'articles techniques liés à PHP, veuillez visiter la colonne Tutoriel PHP pour apprendre !

Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

Déclaration:
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn