Build OAuth2.0 service based on thinkphp framework
These days have been engaged in OAuth2.0 things, write SDK what, in order to more in-depth understanding of the service side of the OAuth authentication mechanism, I built a PHP under the OAuth environment, and transplanted it into their own relatively familiar TP framework.
A lot of crap says, start.
?
In fact, there are OAuth2.0 PHP version of the Internet.
You can find the source code in http://code.google.com/p/oauth2-php/, which implements the data pattern for PDO and MongoDB. Here I am also based on this code in the TP integration.
?
OK, here we can download the package to unzip, the Lib under the Oauth.inc renamed to OAuth2.class.php and placed in the directory under the TP core package:
?
/extend/library/org/oauth/oauth2.class.php
?
Next we will inherit this class;
Create a new ThinkOAuth2.class.php file in this directory:
?
db = Db::getinstance (C (' Oauth2_db_dsn ')), $this, table = Array (' Auth_codes ' =>c (' oauth2_codes_table '), ' Clients ' =>c (' oauth2_clients_table '), ' tokens ' =>c (' oauth2_token_table '));} /** * destructor */function __destruct () {$this->db = NULL;//Release db connection}private function handleexception ($e) {echo "Database Error:". $e->getmessage (); exit;} /** * * Add client * @param string $client _id * @param string $client _secret * @param string $redirect _uri */public functio N Addclient ($client _id, $client _secret, $redirect _uri) {$time = time (); $sql = "INSERT into {$this, table[' clients ')} "." (client_id, Client_secret, Redirect_uri, Create_time) VALUES (\ "{$client _id}\", \ "{$client _secret}\", \ "{$redirect _uri}\", \ "{$time}\") ", $this, DB, execute ($sql);} /** * Implements oauth2::checkclientcredentials () * @see oauth2::checkclientcredentials () */protected function Checkclientcredentials ($client _id, $client _secret = NULL) {$sql = "Select Client_secret from {$this table[' Clients ']} "." WHERE client_id = \ "{$client _id}\" "; $result = $this, db, Query ($sql); if ($client _secret = = = NULL) {return $resul T!== FALSE;} Log::write ("Checkclientcredentials:". $result);//log::write ("Checkclientcredentials:". $result [0]);//log:: Write ("Checkclientcredentials:". $result [0]["Client_secret"]); return $result [0]["client_secret"] = = $client _secret ;} /** * Implements Oauth2::getredirecturi (). * @see Oauth2::getredirecturi () */protected function Getredirecturi ($client _id) {$sql = "Select Redirect_uri from {$this- > table[' clients '} "." WHERE client_id = \ "{$client _id}\" "; $result = $this, db, Query ($sql); if ($result = = = False) {return false;} Log::write ("Getredirecturi:". $result);//log::write ("Getredirecturi:". $result [0]);//log::write (" Getredirecturi: ". $result [0][" Redirect_uri "]), return isset ($result [0][" Redirect_uri "]) && $result [0][] Redirect_uri "]? $result [0]["Redirect_uri"]: NULL;} /** * Implements Oauth2::getaccesstoken (). * @see OAuth2::getaccesstoken () */protected function Getaccesstoken ($access _token) {$sql = "Select client_id, Expires, scope From {$this-table[' tokens '} "." WHERE Access_token = \ "{$access _token}\" "; $result = $this, db, Query ($sql);//log::write (" Getaccesstoken: ". $re Sult);//log::write ("Getaccesstoken:". $result [0]); return $result!== FALSE? $result: NULL;} /** * Implements Oauth2::setaccesstoken (). * @see Oauth2::setaccesstoken () */protected function Setaccesstoken ($access _token, $client _id, $expires, $scope = NULL) { $sql = "INSERT into {$this table[' tokens '}". " (Access_token, client_id, expires, scope) "." VALUES (\ "{$access _token}\", \ "{$client _id}\", \ "{$expires}\", \ "{$scope}\") ", $this, DB, execute ($sql);} /** * Overrides oauth2::getsupportedgranttypes (). * @see oauth2::getsupportedgranttypes () */protected function getsupportedgranttypes () {return Array (oauth2_grant_type _auth_code);} /** * Overrides Oauth2::getauthcode (). * @see Oauth2::getauthcode () */protected function Getauthcode ($code) {$sql = "Select Code, CLIENT_ID, Redirect_uri, expires, scope". From {$this, table[' Auth_codes '}, WHERE code = \ "{$code}\" "; $result = $this, db, Query ($sql);//log::write (" Getauthcode: ". $result);//log::write (" Getauthcode: ". $result [0]);//log::write (" Getauthcode: ". $result [0][" code "]) ; return $result!== FALSE? $result [0]: NULL;} /** * Overrides Oauth2::setauthcode (). * @see Oauth2::setauthcode () */protected function Setauthcode ($code, $client _id, $redirect _uri, $expires, $scope = NULL) { $time = Time (), $sql = "INSERT into {$this, table[' Auth_codes '}". " (Code, CLIENT_ID, Redirect_uri, expires, scope) "." VALUES (\ "${code}\", \ "${client_id}\", \ "${redirect_uri}\", \ "${expires}\", \ "${scope}\") "; $result = $this db-- > Execute ($sql); }/** * Overrides oauth2::checkusercredentials (). * @see oauth2::checkusercredentials () */protected function checkusercredentials ($client _id, $username, $password) {RE Turn TRUE; }}
?
? Here we need to create a database:
?
CREATE TABLE ' oauth_client ' (' ID ' bigint () not null auto_increment, ' client_id ' varchar (+) NOT NULL, ' Client_secret ' varchar (+) NOT null, ' Redirect_uri ' varchar ($) NOT null, ' create_time ' int () default NULL, PRIMARY KEY (' id ')) Engine=myisam auto_increment=3 DEFAULT Charset=utf8; CREATE TABLE ' Oauth_code ' (' ID ' bigint () not null auto_increment, ' client_id ' varchar (+) NOT null, ' user_id ' varcha R (+) not NULL, ' code ' varchar (+) NOT null, ' Redirect_uri ' varchar ($) NOT NULL, ' expires ' int (one) not null, ' scope ' varchar (+) default NULL, PRIMARY KEY (' id ')) engine=myisam default Charset=utf8; CREATE TABLE ' Oauth_token ' (' ID ' bigint () not null auto_increment, ' client_id ' varchar (+) NOT null, ' user_id ' Varch AR (+) not null, ' access_token ' varchar (+) NOT null, ' refresh_token ' varchar (+) NOT NULL, ' expires ' int (one) not NULL, ' Scope ' varchar ($) Default NULL, PRIMARY KEY (' id ')) engine=myisam auto_increment=2 default Charset=utf8;
?
?
The database table name above can be arbitrarily fixed, but to configure the table name in config.php:
?
' oauth2_codes_table ' = ' oauth_code ', ' oauth2_clients_table ' = ' oauth_client ', ' oauth2_token_table ' and ' = ' Oauth_token ',
?
If the OAuth server is not the current server, then the DSN address must be defined:
?
?
' Oauth2_db_dsn ' = ' mysql://root:[email protected]:3306/database '
?
?
Okay, so that's the approximate core library code. The next step is to use it
?
We create an OAuth action that is responsible for some validation of OAuth2 (OauthAction.class.php)
?
Import ("ORG. Oauth.thinkoauth2 "), class Oauthaction extends Action {private $oauth = Null;function _initialize () {Header (" Content-type:application/json ");Header ("Cache-control:no-store"), $this, OAuth = new ThinkOAuth2 (); Public Function Index () {header ("Content-type:application/json; Charset=utf-8 "), $this-Ajaxreturn (null, ' Oauth-server-start ', 1, ' json '); } public Function Access_token () {$this, OAuth, Grantaccesstoken ();} Permission validation Public Function authorize () {if ($_post) {$this, OAuth, Finishclientauthorization ($_post["accept"] = = "Ye P ", $_post); return;} form Preparation $auth_params = OAuth, $this, Getauthorizeparams (), $this, assign ("params", $auth _params); $this- >display ();} Public Function addclient () {if ($_post && isset ($_post["client_id"]) && isset ($_post["Client_secret"] ) && isset ($_post["Redirect_uri")) {$this, OAuth, Addclient ($_post["client_id"], $_post["Client_ Secret "], $_post[" Redirect_uri "]); return;} $this->display ();}}
?
?
Here we create a private OAuth object and go to init it at initialization time.
?
The above code is not validated in the password section, and the third pattern requires rewriting the Checkusercredentials method in the Thinkoauth class.
?
Go ahead, we write a restricted resource code. We are not using AOP to intercept, so I'm going to use a base class directly to simulate interception.
?
?
Import ("ORG. Oauth.thinkoauth2 "), class Baseaction extends Action {protected $oauth = Null;function _initialize () {$this, OAuth = NE W ThinkOAuth2 (); } Public Function Index () { if (! $this, OAuth-Verifyaccesstoken ()) { $this-ajaxreturn (null, ' No,no, No ', 0, ' json '); Exit (); } $this-Ajaxreturn (null, ' Oauth-server ', 1, ' json '); } }
?
? Next, use a useraction to inherit it for a limited purpose, as follows:
?
?
Class Useraction extends Baseaction {public function index () {if (! $this, OAuth, Verifyaccesstoken ()) { $this-Ajaxreturn (null, ' No,no,no ', 0, ' json '); } $this-Ajaxreturn (null, ' Oauth-server ', 1, ' json '); } }
?
?
?
?
Finally, why do you want to couple user_id into the OAuth table? Because we sometimes need to return from Access_token to check user_id, the above table can solve this problem, but in fact there is a way to automatically include user_id for Access_token generation, and then encrypt, when decoding from Access_ Tokens can be removed directly from the user_id. Here about user_id and password authentication are not implemented, you need to inherit the ThinkOAuth2 class later or modify the Checkusercredentials method to achieve.? In addition this set of things used in rest mode I think better!