PHP Token (token) Design _php skills

Source: Internet
Author: User
Tags md5 rand


How to achieve the goal:

How do I avoid duplicate submissions?
In the session, you save an array, which is stored in a successfully submitted token. In the background processing, first determine whether the token is in this array, if it exists, the description is repeated submissions.
How to check the antecedents?
Optional, this token is added to the current session_id when it is generated. If someone else copy your HTML (token a copy), in the submission, theoretically token contains session_id not equal to the current session_id, You can judge this submission as an external submission.
How do I match an action to be performed?
In the token, to the token of the action name into this token, so, in processing, the action to solve the comparison on the line.
The Gtoken I wrote earlier could not reach the second one mentioned above, and I modified it today to add the function 2. Personal feeling is OK.
Please see the code, feel where there is unreasonable place, please enlighten me! Thank you.

Encryption I was looking for a method of the Internet, slightly modified.

GEncrypt.inc.php:

Copy Code code as follows:

<?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 + +) {
$MD 5 = substr ($txt, $i, 1);
$i + +;
$tmp. = (substr ($txt, $i, 1) ^ $md 5);
}
return $tmp;
}
}
?>

GToken.inc.php
Method:

A,grantetoken parameter: FormName, which is the action name, key is the encryption/decryption key.
Returns a string, in the form of: encryption (FORMNAME:SESSION_ID)

B,istoken parameters: Token that is the result of Grantetoken, FormName, action name, fromcheck whether to check the antecedents, if true, but also to determine token whether the session_id and the current session_id one to.

C,droptoken, when a successful action is executed, call this function, and write this token into the session,

Copy Code code as follows:

<?php
/**
* Principle: When requesting allocation of token, try to allocate a unique token, base64 (time + rand + action)
* If submitted, place this token record stating that this token is used and can be followed to avoid duplicate submissions.
*
*/
Class Gtoken {

/**
* Get all the current token
*
* @return Array
*/
public static function Gettokens () {
$tokens = $_session[gconfig::session_key_token];
if (Empty ($tokens) &&!is_array ($tokens)) {
$tokens = Array ();
}
return $tokens;
}

/**
* To produce a new token
*
* @param string $formName
* @param encryption Key $key
* @return String
*/

public static function Grantetoken ($formName, $key = Gconfig::encrypt_key) {
$token = Gencrypt::encrypt ($formName. ":". session_id (), $key);
return $token;
}

/**
* Delete token, in fact, add an element to an array of sessions to show that the token has been used to avoid duplication of data submissions.
*
* @param string $token
*/
public static function Droptoken ($token) {
$tokens = Self::gettokens ();
$tokens [] = $token;
Gsession::set (Gconfig::session_key_token, $tokens);
}

/**
* Check to see if the specified token
*
* @param string $token The token value to check
* @param string $formName
* @param boolean $fromCheck whether to check the routing and, if true, to determine whether the attached session_id in token is the same as the current session_id.
* @param string $key encryption key
* @return Boolean
*/

public static function Istoken ($token, $formName, $fromCheck = False, $key = Gconfig::encrypt_key) {
$tokens = Self::gettokens ();

if (In_array ($token, $tokens))//If present, the description is in use token
return false;

$source = Split (":", Gencrypt::d ecrypt ($token, $key));

if ($fromCheck)
return $source [1] = = session_id () && $source [0] = = $formName;
Else
return $source [0] = = $formName;
}
}
?>
Example:

First from the $_post to take out token, with Istoken judge.

-->Include (".. /common.inc.php ");  <BR> $token  = $_post[" token "];  <BR>if  (Gtoken::istoken ( $token, "Adminlogin", True)  {  <BR>     $vCode  = $_post["Vcode"];   <BR>    if  (Strtoupper ($vCode)  != strtoupper ($_session[gconfig: : session_key_validate_code ])  {  <BR>         Throw new exception ("Verify code is incorrect!) ");  <BR>    }  <BR>           <BR>     $vo  = new vo_admin ();  <BR>      $vo->setnickname ($_post["name"]);  <BR>     $vo->setpwd ($_post["pwd"] );  <BR>      <BR>     $mo  = new mo_ Admin ();  <BR>     $mo->setvo ($VO);  <BR>      <BR>      <BR>      $f  =  $mo->login ();  <br>    if (! $f) {  <BR>         throw new exception ("Username or password is incorrect!) ");  <BR>    }else{  <BR>         gtoken::d roptoken ($token);  <br>        //header (" Location: ". Gdir::getrelativepath ("/admin/index.php"));  <BR>         echo  "Here";  //if externally submitted, this sentence will not print out!  <BR>    }  <BR>}  <BR> $sFile  = gdir::getabspath (gconfig::D ir_serialize , "Admin/login");  <BR> $TPL  = gserialize::load ($sFile);  <BR>if  ($tpl  === false)  {  <br >   &nBSP; $tpl  = new gtpl (gconfig::D ir_skin ,gconfig::D ebug_tpl_file );  <BR>      $tpl->load (  <BR>         Header "    =>    " admin/header.html ",  <BR>          "Footer"     =>     "admin/ footer.html ",  <BR>        " Admlogin "     =>     "admin/login.html",  <BR>          "Admloginjs" =>     "admin/loginjs.html"   <BR>     ));      <br>    gserialize::save ($TPL, $sFile);  <BR>}  <BR> $tpl->assign ("title", "Admin login");  <BR> $tpl->assign ("path", Gdir:: Getrelativepath (Site_dir)); &nbsP <BR> $tpl->assign ("Vimg", Gdir::getrelativepath ("/vimg.php"));  <BR>if  (mo_admin:: Islogined ())  {  <BR>     $tpl->parseblock ("blk_logined");  <BR> }else {  <BR>     $tpl->assign ("token", Gtoken::grantetoken ("Adminlogin")) ;  <BR>     $tpl->parseblock ("blk_loadscripts", "Cond_notlogin");       <BR>     $tpl->parseblock ("Blk_notlogin");  <br>}   <BR>echo  $tpl->parse ("header");  <BR>echo  $tpl->parse ("Admlogin");  <BR>echo  $tpl->parse ("footer");  <BR>echo  $tpl->parse ("Admloginjs");  < Br>?> <br> "target=" _blank "> Download this file It all looks as if there is no problem.
If you want to determine whether the matching action is performed, you can change the formname in the Istoken, run, very well, no match. Prove this success.

Whether I can avoid repeated submissions, I have no validation, too simple logic.

The rest is to determine whether the routing check is working properly.
The above example generates HTML copy to a local Web page (to achieve the purpose of a different domain), runs, checks out, and does not perform an action (you need to set the third argument of Istoken to true).
Set the third parameter of Istoken to False, commit, and execute the specified action!

OK, so far, do not know where there is a bug, this will be in the long-term use of slowly debugging changes!

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.