Heim  >  Artikel  >  Backend-Entwicklung  >  PHP-Token-Design (Token).

PHP-Token-Design (Token).

WBOY
WBOYOriginal
2016-08-08 09:26:491447Durchsuche

Nachdruck-Link: http://www.jb51.net/article/13756.htm

Ziel des PHP-Token-Designs: Vermeiden Sie die wiederholte Übermittlung von Daten, um festzustellen, ob es sich um eine externe Übermittlung handelt Passen Sie die auszuführende Aktion an (wenn mehrere Logiken auf derselben Seite implementiert sind, z. B. das Hinzufügen, Löschen und Ändern von Vorgängen in einer PHP-Datei). Das hier erwähnte Token ist ein verstecktes Token, das beim Anzeigen der Seite in das FORM geschrieben wird. Formularelement (Typ=versteckt). Wenn es sich um Klartext handelt, muss eine bestimmte Verschlüsselungsmethode verwendet werden. Mein Algorithmus ist sehr idiotisch, daher habe ich a verwendet vorgefertigte Methode im Internet.

Wie vermeide ich wiederholte Übermittlungen?
Speichern Sie ein Array in SESSION. Stellen Sie während der Hintergrundverarbeitung zunächst fest, ob sich das Token in diesem Array befindet. Wenn es existiert, erklären Sie, dass es sich um eine wiederholte Übermittlung handelt.
Optional, wenn dieses Token generiert wird, wird die aktuelle Sitzungs-ID hinzugefügt. theoretisch Wenn die im Token enthaltene Sitzungs-ID nicht mit der aktuellen Sitzungs-ID übereinstimmt, können Sie feststellen, dass es sich bei dieser Übermittlung um eine externe Übermittlung handelt.
Wie wird die auszuführende Aktion abgeglichen?
Bei der Tokenisierung muss der Aktionsname dieses Tokens in das Token geschrieben werden, damit die Aktion während der Verarbeitung zum Vergleich dekodiert werden kann.

GEncrypt.inc.php:

Methode:

<?php  
class GEncrypt extends GSuperclass {  
    protected static function keyED($txt,$encrypt_key){     
        $encrypt_key = md5($encrypt_key);     
        $ctr=0;     
        $tmp = "";     
        for ($i=0;$i<strlen($txt);$i++){     
            if ($ctr==strlen($encrypt_key)) $ctr=0;     
            $tmp.= substr($txt,$i,1) ^ substr($encrypt_key,$ctr,1);     
            $ctr++;     
        }     
        return $tmp;     
    }  

    public static function encrypt($txt,$key){     
        //$encrypt_key = md5(rand(0,32000));  
        $encrypt_key = md5(((float) date("YmdHis") + rand(10000000000000000,99999999999999999)).rand(100000,999999));  
        $ctr=0;     
        $tmp = "";     
        for ($i=0;$i<strlen($txt);$i++){  
            if ($ctr==strlen($encrypt_key)) $ctr=0;     
            $tmp.= substr($encrypt_key,$ctr,1) . (substr($txt,$i,1) ^ substr($encrypt_key,$ctr,1));     
            $ctr++;     
        }     
        return base64_encode(self::keyED($tmp,$key));  
    }  

    public static function decrypt($txt,$key){  
        $txt = self::keyED( base64_decode($txt),$key);     
        $tmp = "";  
        for ($i=0;$i<strlen($txt);$i++){     
            $md5 = substr($txt,$i,1);     
            $i++;     
            $tmp.= (substr($txt,$i,1) ^ $md5);     
        }  
        return $tmp;  
    }      
}  
?> 
(1) granteToken-Parameter: formName, der der Aktionsname ist, key ist der Verschlüsselungs-/Entschlüsselungsschlüssel
Gibt eine Zeichenfolge in der Form zurück (formName: session_id)
(2) isToken-Parameter: Token ist das von granteToken, formName, Aktionsname generierte Ergebnis. Ob fromCheck den Ursprung überprüft. Wenn dies wahr ist, muss auch festgestellt werden, ob die session_id im Token vorhanden ist Identisch mit der aktuellen Sitzungs-ID.
(3) dropToken, rufen Sie nach erfolgreicher Ausführung einer Aktion diese Funktion auf und zeichnen Sie das Token in der Sitzung auf,

GToken.inc.php

<?php  
/**  
* 原理:请求分配token的时候,想办法分配一个唯一的token, base64( time + rand + action)  
* 如果提交,将这个token记录,说明这个token以经使用,可以跟据它来避免重复提交。  
*  
*/  
class GToken {  

    /**  
     * 得到当前所有的token  
     *  
     * @return array  
     */  
    public static function getTokens(){  
        $tokens = $_SESSION[GConfig::SESSION_KEY_TOKEN ];  
        if (empty($tokens) && !is_array($tokens)) {  
            $tokens = array();  
        }  
        return $tokens;  
    }  

    /**  
     * 产生一个新的Token  
     *  
     * @param string $formName  
     * @param 加密密钥 $key  
     * @return string  
     */  

    public static function granteToken($formName,$key = GConfig::ENCRYPT_KEY ){  
        $token = GEncrypt::encrypt($formName.":".session_id(),$key);  
        return $token;  
    }  

    /**  
     * 删除token,实际是向session 的一个数组里加入一个元素,说明这个token以经使用过,以避免数据重复提交。  
     *  
     * @param string $token  
     */  
    public static function dropToken($token){  
        $tokens = self::getTokens();  
        $tokens[] = $token;  
        GSession::set(GConfig::SESSION_KEY_TOKEN ,$tokens);  
    }  

    /**  
     * 检查是否为指定的Token  
     *  
     * @param string $token    要检查的token值  
     * @param string $formName  
     * @param boolean $fromCheck 是否检查来路,如果为true,会判断token中附加的session_id是否和当前session_id一至.  
     * @param string $key 加密密钥  
     * @return boolean  
     */  

    public static function isToken($token,$formName,$fromCheck = false,$key = GConfig::ENCRYPT_KEY){  
        $tokens = self::getTokens();  

        if (in_array($token,$tokens)) //如果存在,说明是以使用过的token  
            return false;  

        $source = split(":", GEncrypt::decrypt($token,$key));  

        if($fromCheck)  
            return $source[1] == session_id() && $source[0] == $formName;  
        else  
            return $source[0] == $formName;  
    }  
}  
?> 
von $_POST Herausnehmen das Token von isToken und verwenden Sie isToken, um zu beurteilen, ob es sich um eine übereinstimmende Aktion handelt. Sie können den formNamen in isToken ändern und es ausführen Erfolg.
Das Obige stellt das Design des PHP-Tokens vor, einschließlich verschiedener Aspekte. Ich hoffe, dass es für Freunde hilfreich ist, die sich für PHP-Tutorials interessieren.

Stellungnahme:
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn