PHPToken (token) design _ PHP Tutorial

Source: Internet
Author: User
PHPToken (token) design. How to achieve the goal: How to avoid repeated submission? You need to store an array in the SESSION. this array is used to store successfully submitted tokens. when processing in the background, first determine whether the token is in this array for the purpose:

How to avoid repeated submission?
You need to store an array in the SESSION, which is saved as the token successfully submitted. when processing in the background, first determine whether the token is in this array. If yes, it indicates repeated submission.
How do I check the routes?
Optional. The current session_id is added when the token is generated. if someone else copies your html (token one burst copy), the session_id contained in the token is not equal to the current session_id theoretically during submission, you can determine that this submission is an external commit.
How to match the action to be executed?
During the token operation, you need to write the token action name into the token. in this way, you can parse the action and compare it during processing.
The GToken I wrote earlier cannot reach the second one mentioned above. I modified it today and added function 2. I personally feel that it is okay.
Let's take a look at the code and tell us what is unreasonable! Thank you.

I am looking for a method on the Internet to encrypt it. I made a slight modification.

GEncrypt. inc. php:

The code is as follows:


Class GEncrypt extends GSuperclass {
Protected static function keyED ($ txt, $ encrypt_key ){
$ Encrypt_key = md5 ($ encrypt_key );
$ Ctr = 0;
$ Tmp = "";
For ($ I = 0; $ 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, 3 ));
$ Encrypt_key = md5 (float) date ("YmdHis") + rand (random gain ,99999999999999999). rand (100000,999999 ));
$ Ctr = 0;
$ Tmp = "";
For ($ I = 0; $ 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 $ Md5 = substr ($ txt, $ I, 1 );
$ I ++;
$ Tmp. = (substr ($ txt, $ I, 1) ^ $ md5 );
}
Return $ tmp;
}
}
?>


GToken. inc. php
Method:

A, granteToken parameter: formName, that is, action name. key is the encryption/decryption key.
Returns a string in the format of encryption (formName: session_id)

B. isToken parameter: indicates the result generated by granteToken, formName, action name, and fromCheck. if it is true, check whether the session_id in the token is the same as the current session_id.

C. dropToken. after a successful action is executed, call this function to record the token to the session,

The code is as follows:


/**
* Principle: a unique token, base64 (time + rand + action)
* If the token is submitted, it indicates that the token is used. you can follow the token to avoid repeated submission.
*
*/
Class GToken {

/**
* Get all the current tokens.
*
* @ Return array
*/
Public static function getTokens (){
$ Tokens = $ _ SESSION [GConfig: SESSION_KEY_TOKEN];
If (empty ($ tokens )&&! Is_array ($ tokens )){
$ Tokens = array ();
}
Return $ tokens;
}

/**
* Generate 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;
}

/**
* Deleting a token actually adds an element to an array of sessions, indicating that the token has been used to avoid repeated data submission.
*
* @ Param string $ token
*/
Public static function dropToken ($ token ){
$ Tokens = self: getTokens ();
$ Tokens [] = $ token;
GSession: set (GConfig: SESSION_KEY_TOKEN, $ tokens );
}

/**
* Check whether the specified Token is used.
*
* @ Param string $ the token value to be checked
* @ Param string $ formName
* @ Param boolean $ fromCheck whether to check the route. if it is true, it determines whether the session_id appended to the 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 yes, it indicates that it is a used token.
Return false;

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

If ($ fromCheck)
Return $ source [1] = session_id () & $ source [0] = $ formName;
Else
Return $ source [0] = $ formName;
}
}
?>

Example:

First, retrieve the token from $ _ POST and use isToken to judge the token.

It seems that it is okay to download this file.
If you want to determine whether the matching action is executed, you can change the formName in isToken to run it. it is very good and does not match. this proves successful.

Can I avoid repeated submission? I didn't verify it. it's too simple logic.

The rest is to determine whether the road check is normal.
Copy the html generated in the preceding example to a local webpage (for the purpose of different domains), run the script, and check whether the origin is unknown, no action is executed (set the third parameter of isToken to true ).
Set the third parameter of isToken to false, submit, and the specified action is executed!

Okay, so far, I don't know where there is a BUG, so I have to debug and modify it for a long time!

How can I avoid repeated commit? You need to store an array in the SESSION. this array is used to store successfully submitted tokens. when processing in the background, you must first determine whether the token is in this array...

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.