入って来い! ログインおよびパスワードなしの認証、v2

聴衆は、ユーザーを特定できる1回限りの(ある程度の作業を行う)リンクの作成などのトピックに無関心ではないことが判明したためです。



そして、特に私はそのような解決策(以下に公開する)をより受け入れやすいと考えるという事実に照らして-私はこの問題の解決策をどう見るかを書くことにしました:



すべてがデータベースに保存されます。 Mysqlが手元にあるからです。 postgre、Oracle、およびsqlサーバーの場合、ソリューションは99%類似しています。



収納テーブル:



Copy Source | Copy HTML CREATE TABLE test.one_time_auth( token CHAR (32), user_id INT (11) UNSIGNED NOT NULL , expire DATETIME DEFAULT NULL , PRIMARY KEY (token) ) ENGINE = INNODB



  1. Copy Source | Copy HTML CREATE TABLE test.one_time_auth( token CHAR (32), user_id INT (11) UNSIGNED NOT NULL , expire DATETIME DEFAULT NULL , PRIMARY KEY (token) ) ENGINE = INNODB



  2. Copy Source | Copy HTML CREATE TABLE test.one_time_auth( token CHAR (32), user_id INT (11) UNSIGNED NOT NULL , expire DATETIME DEFAULT NULL , PRIMARY KEY (token) ) ENGINE = INNODB



  3. Copy Source | Copy HTML CREATE TABLE test.one_time_auth( token CHAR (32), user_id INT (11) UNSIGNED NOT NULL , expire DATETIME DEFAULT NULL , PRIMARY KEY (token) ) ENGINE = INNODB



  4. Copy Source | Copy HTML CREATE TABLE test.one_time_auth( token CHAR (32), user_id INT (11) UNSIGNED NOT NULL , expire DATETIME DEFAULT NULL , PRIMARY KEY (token) ) ENGINE = INNODB



  5. Copy Source | Copy HTML CREATE TABLE test.one_time_auth( token CHAR (32), user_id INT (11) UNSIGNED NOT NULL , expire DATETIME DEFAULT NULL , PRIMARY KEY (token) ) ENGINE = INNODB



  6. Copy Source | Copy HTML CREATE TABLE test.one_time_auth( token CHAR (32), user_id INT (11) UNSIGNED NOT NULL , expire DATETIME DEFAULT NULL , PRIMARY KEY (token) ) ENGINE = INNODB



  7. Copy Source | Copy HTML CREATE TABLE test.one_time_auth( token CHAR (32), user_id INT (11) UNSIGNED NOT NULL , expire DATETIME DEFAULT NULL , PRIMARY KEY (token) ) ENGINE = INNODB







さて、今ではクラス自体+それを使った作業の例。 この例では、最初に今年の12月31日までの期間のトークンを作成し、次にそれを取得します。



Copy Source | Copy HTML



  1. <?php
  2. $ db = 新しい PDO'mysql:host = 127.0.0.1; dbname = test''root' );
  3. $ db-> setAttribute( PDO :: ATTR_ERRMODE、 PDO :: ERRMODE_EXCEPTION);
  4. $ auth = new one_time_auth( $ db );
  5. $ token = $ auth- > remember( 10'2010-12-31' );
  6. $ user_id = $ auth- > remind( $ token );
  7. echo $ user_id ;
  8. クラス one_time_auth
  9. {
  10. / ** <br/> * @var PDO <br/> * /
  11. プライベート $ db ;
  12. パブリック関数 __construct( PDO $ db
  13. {
  14. $ this-> db = $ db ;
  15. }
  16. public function remember( $ user_id$ expire = null
  17. {
  18. $ sql = 'INSERT INTO one_time_auth(token、user_id、expire)VALUES(:token ,: user_id ,: expire)' ;
  19. $ stmt = $ this-> db-> prepare( $ sql );
  20. whiletrue ){
  21. {
  22. $ stmt- > execute( array
  23. ':トークン' => $ token = $ this- > generateToken()、
  24. 'user_id' => $ user_id
  25. 'expire' => $ expire
  26. ));
  27. 休憩 ;
  28. } catchPDOException $ e ){}
  29. }
  30. $トークンを 返し ます
  31. }
  32. パブリック関数リマインド( $トークン
  33. {
  34. $ sql = 'SELECT user_id <br/> FROM one_time_auth <br/> WHERE token =:token <br/> AND(expire IS NULL OR expire <= NOW()) <br /> LIMIT 1' ;
  35. $ stmt = $ this-> db-> prepare( $ sql );
  36. $ stmt- > execute( array'token' => $ token ));
  37. if$ row = $ stmt- > fetch()){
  38. $ stmt = $ this- > db-> prepare( 'DELETE FROM one_time_auth WHERE token =:token' );
  39. $ stmt- > execute( array'token' => $ token ));
  40. return $ row [ 'user_id' ];
  41. }
  42. }
  43. プライベート関数 generateToken()
  44. {
  45. return md5(uniqid( ''true ));
  46. }
  47. }


PS:コードはトピックhabrahabr.ru/blogs/php/109421への答えとして「膝の上に」書かれました



PPS:md5()についてすぐに明確にしたいと思います-このコンテキストのこの関数は「穴」を追加せず、ハッシュを取得する方法にすぎません。 必要に応じて、sha1()、または必要に応じて他のものに置き換えることができます。 主なアイデアは、ユーザーデータに縛られる必要がないということです。



All Articles