per-session token
私はセキュリティを強化するために使用するよりも、最も安全であるが使いやすさに影響を与えるper-form/url token
と主張する人もいるかもしれません。per-request token
また、セッションストレージをトークンストレージから分離し、のようなものを使用する方が良いと思いますMemcache
。expiration to the token
これは、複数のアプリケーションサーバーなどを使用して速度が必要な場合に適しています。全体に影響を与えることなくカスタムを追加できるので、私もそれを好みます。session
これが典型的な例です
HTML
<form method="POST" action="#">
IP:<input type="text" name="IP" /> <input type="hidden" name="token"
value="<?php echo Token::_instance()->generate(); ?>" /> <input
type="Submit" value="Login" />
</form>
処理
$id = "id44499900";
Token::_instance()->initialise($id); // initialise with session ID , user ID or IP
try {
Token::_instance()->authenticate();
// Process your form
} catch ( TokenException $e ) {
http_response_code(401); // send HTTP Error 401 Unauthorized
die(sprintf("<h1>%s</h1><i>Thief Thief Thief</i>", $e->getMessage()));
}
使用したクラス
class Token {
private $db;
private $id;
private static $_instance;
function __construct() {
$this->db = new Memcache();
$this->db->connect("localhost");
}
public static function _instance() {
self::$_instance === null and self::$_instance = new Token();
return self::$_instance;
}
public function initialise($id) {
$this->id = $id;
}
public function authenticate(array $source = null, $key = "token") {
$source = $source !== null ? $source : $_POST;
if (empty($this->id)) {
throw new TokenException("Token not Initialised");
}
if (! empty($source)) {
if (! isset($source[$key]))
throw new TokenException("Missing Token");
if (! $this->get($this->id . $source[$key])) {
throw new TokenException("Invalid Token");
}
}
}
public function get($key) {
return $this->db->get($key);
}
public function remove($key) {
return $this->db->delete($key);
}
public function generate($time = 120) {
$key = hash("sha512", mt_rand(0, mt_getrandmax()));
$this->db->set($this->id . $key, 1, 0, $time);
return $key;
}
}
class TokenException extends InvalidArgumentException {
}
注:トークンは120
秒後に自動的に削除され、ユーザーフレンドリーな機能に影響を与える可能性があるため、この例は[戻る]ボタンまたは更新に影響を与える可能性があることに注意してください