├── README
├── class
├── Consumer.class.php
├── Db.class.php
├── Provider.class.php
├── Token.class.php
└── User.class.php
├── client
├── apicall.php
├── callback.php
└── index.php
├── interfaces
├── IConsumer.php
├── IToken.php
└── IUser.php
├── oauth
├── .htaccess
├── index.php
└── login.php
└── sql
└── schema.sql
/README:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/djpate/OAuthProviderExample/251bc14715c7933490caf58c167a2a76cb47ce64/README
--------------------------------------------------------------------------------
/class/Consumer.class.php:
--------------------------------------------------------------------------------
1 | query("select id from consumer where consumer_key = '".$key."'"); // this is not safe !
20 | if($info->rowCount()==1){
21 | $info = $info->fetch();
22 | $consumer = new Consumer($info['id']);
23 | }
24 | return $consumer;
25 | }
26 |
27 | public function __construct($id = 0){
28 | $this->pdo = Db::singleton();
29 | if($id != 0){
30 | $this->id = $id;
31 | $this->load();
32 | }
33 | }
34 |
35 | private function load(){
36 | $info = $this->pdo->query("select * from consumer where id = '".$this->id."'")->fetch();
37 | $this->id = $this->id;
38 | $this->key = $info['consumer_key'];
39 | $this->secret = $info['consumer_secret'];
40 | $this->active = $info['active'];
41 | }
42 |
43 | public static function create($key,$secret){
44 | $pdo = Db::singleton();
45 | $pdo->exec("insert into consumer (consumer_key,consumer_secret,active) values ('".$key."','".$secret."',1)");
46 | $consumer = new Consumer($pdo->lastInsertId());
47 | return $consumer;
48 | }
49 |
50 | public function isActive(){
51 | return $this->active;
52 | }
53 |
54 | public function getKey(){
55 | return $this->key;
56 | }
57 |
58 | public function getSecretKey(){
59 | return $this->secret;
60 | }
61 |
62 | public function getId(){
63 | return $this->id;
64 | }
65 |
66 | public function hasNonce($nonce,$timestamp){
67 | $check = $this->pdo->query("select count(*) as cnt from consumer_nonce where timestamp = '".$timestamp."' and nonce = '".$nonce."' and consumer_id = ".$this->id)->fetch();
68 | if($check['cnt']==1){
69 | return true;
70 | } else {
71 | return false;
72 | }
73 | }
74 |
75 | public function addNonce($nonce){
76 | $check = $this->pdo->exec("insert into consumer_nonce (consumer_id,timestamp,nonce) values (".$this->id.",".time().",'".$nonce."')");
77 | }
78 |
79 | /* setters */
80 |
81 | public function setKey($key){
82 | $this->key = $key;
83 | }
84 |
85 | public function setSecret($secret){
86 | $this->secret = $secret;
87 | }
88 |
89 | public function setActive($active){
90 | $this->active = $active;
91 | }
92 |
93 | public function setId($id){
94 | $this->id = $id;
95 | }
96 |
97 | }
98 |
99 | ?>
100 |
--------------------------------------------------------------------------------
/class/Db.class.php:
--------------------------------------------------------------------------------
1 |
2 | /* this is nothing else but a PDO wrapper */
3 | class Db {
4 |
5 | private $pdoInstance;
6 |
7 | private static $instance;
8 |
9 | private function __construct() {
10 | $this->pdoInstance = new PDO("mysql:host=localhost;dbname=oauthProvider","oauth","oauth");
11 | $this->pdoInstance->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
12 | $this->pdoInstance->exec("set names 'utf8'");
13 | }
14 |
15 | private function __clone() {}
16 |
17 | public static function singleton() {
18 |
19 | if (!isset(self::$instance)) {
20 | $c = __CLASS__;
21 | self::$instance = new $c;
22 | }
23 |
24 | return self::$instance;
25 |
26 | }
27 |
28 | /* pdo functions */
29 |
30 | public function quote($str){
31 | return $this->pdoInstance->quote($str);
32 | }
33 |
34 | public function lastInsertId(){
35 | return $this->pdoInstance->lastInsertId();
36 | }
37 |
38 | public function query($str){
39 | try {
40 | return $this->pdoInstance->query($str);
41 | } catch (PDOException $e) {
42 | echo "Error :
".$str."
". $e->getMessage() . "
".$e->getTraceAsString();
43 | exit;
44 | }
45 | }
46 |
47 | public function exec($str){
48 | try {
49 | return $this->pdoInstance->exec($str);
50 | } catch (PDOException $e) {
51 | echo "Error :
".$str."
". $e->getMessage() . "
".$e->getTraceAsString();
52 | exit;
53 | }
54 | }
55 |
56 | }
57 | ?>
58 |
--------------------------------------------------------------------------------
/class/Provider.class.php:
--------------------------------------------------------------------------------
1 | oauth = new OAuthProvider();
21 |
22 | /* setup check functions */
23 | $this->oauth->consumerHandler(array($this,'checkConsumer'));
24 | $this->oauth->timestampNonceHandler(array($this,'checkNonce'));
25 | $this->oauth->tokenHandler(array($this,'checkToken'));
26 |
27 | }
28 |
29 | /**
30 | * This function check the handlers that we added in the constructor
31 | * and then checks for a valid signature
32 | */
33 | public function checkRequest(){
34 | /* now that everything is setup we run the checks */
35 | try{
36 | $this->oauth->checkOAuthRequest();
37 | } catch(OAuthException $E){
38 | echo OAuthProvider::reportProblem($E);
39 | $this->oauth_error = true;
40 | }
41 | }
42 |
43 | /**
44 | * This function is called when you are requesting a request token
45 | * Basicly it disabled the tokenHandler check and force the oauth_callback parameter
46 | */
47 | public function setRequestTokenQuery(){
48 | $this->oauth->isRequestTokenEndpoint(true);
49 | $this->oauth->addRequiredParameter("oauth_callback");
50 | }
51 |
52 | /**
53 | * This function generates a Request token
54 | * and save it in the db
55 | * then returns the oauth_token, oauth_token_secret & the authentification url
56 | * Please note that the authentification_url is not part of the oauth protocol but I added it to show you how to add extra parameters
57 | */
58 | public function generateRequestToken(){
59 |
60 | if($this->oauth_error){
61 | return false;
62 | }
63 |
64 | $token = sha1(OAuthProvider::generateToken(20,true));
65 | $token_secret = sha1(OAuthProvider::generateToken(20,true));
66 |
67 | $callback = $this->oauth->callback;
68 |
69 | Token::createRequestToken($this->consumer, $token, $token_secret, $callback);
70 |
71 | return "authentification_url=".$this->authentification_url."&oauth_token=".$token."&oauth_token_secret=".$token_secret."&oauth_callback_confirmed=true";
72 |
73 | }
74 |
75 | /**
76 | * This function generates a Access token saves it in the DB and return it
77 | * In that process it also removes the request token used to get that access token
78 | */
79 | public function generateAccesstoken(){
80 |
81 | if($this->oauth_error){
82 | return false;
83 | }
84 |
85 | $access_token = sha1(OAuthProvider::generateToken(20,true));
86 | $secret = sha1(OAuthProvider::generateToken(20,true));
87 |
88 | $token = Token::findByToken($this->oauth->token);
89 |
90 | $token->changeToAccessToken($access_token,$secret);
91 | return "oauth_token=".$access_token."&oauth_token_secret=".$secret;
92 | }
93 |
94 | /**
95 | * This function generates a verifier and returns it
96 | */
97 | public function generateVerifier(){
98 | $verifier = sha1(OAuthProvider::generateToken(20,true));
99 | return $verifier;
100 | }
101 |
102 | /* handlers */
103 |
104 | /**
105 | * This function checks if the consumer exist in the DB and that it is active
106 | * You can modify it at your will but you __HAVE TO__ set $provider->consumer_secret to the right value or the signature will fail
107 | * It's called by OAuthCheckRequest()
108 | * @param $provider
109 | */
110 | public function checkConsumer($provider){
111 | $return = OAUTH_CONSUMER_KEY_UNKNOWN;
112 |
113 | $aConsumer = Consumer::findByKey($provider->consumer_key);
114 |
115 | if(is_object($aConsumer)){
116 | if(!$aConsumer->isActive()){
117 | $return = OAUTH_CONSUMER_KEY_REFUSED;
118 | } else {
119 | $this->consumer = $aConsumer;
120 | $provider->consumer_secret = $this->consumer->getSecretKey();
121 | $return = OAUTH_OK;
122 | }
123 | }
124 |
125 | return $return;
126 | }
127 |
128 | /**
129 | * This function checks the token of the client
130 | * Fails if token not found, or verifier not correct
131 | * Once again you __HAVE TO__ set the $provider->token_secret to the right value or the signature will fail
132 | * It's called by OAuthCheckRequest() unless the client is getting a request token
133 | * @param unknown_type $provider
134 | */
135 | public function checkToken($provider){
136 | $token = Token::findByToken($provider->token);
137 |
138 | if(is_null($token)){ // token not found
139 | return OAUTH_TOKEN_REJECTED;
140 | } elseif($token->getType() == 1 && $token->getVerifier() != $provider->verifier){ // bad verifier for request token
141 | return OAUTH_VERIFIER_INVALID;
142 | } else {
143 | if($token->getType() == 2){
144 | /* if this is an access token we register the user to the provider for use in our api */
145 | $this->user = $token->getUser();
146 | }
147 | $provider->token_secret = $token->getSecret();
148 | return OAUTH_OK;
149 | }
150 |
151 | }
152 |
153 | /**
154 | * This function check both the timestamp & the nonce
155 | * The timestamp has to be less than 5 minutes ago (this is not oauth protocol so feel free to change that)
156 | * And the nonce has to be unknown for this consumer
157 | * Once everything is OK it saves the nonce in the db
158 | * It's called by OAuthCheckRequest()
159 | * @param $provider
160 | */
161 | public function checkNonce($provider){
162 | if($this->oauth->timestamp < time() - 5*60){
163 | return OAUTH_BAD_TIMESTAMP;
164 | } elseif($this->consumer->hasNonce($provider->nonce,$this->oauth->timestamp)) {
165 | return OAUTH_BAD_NONCE;
166 | } else {
167 | $this->consumer->addNonce($this->oauth->nonce);
168 | return OAUTH_OK;
169 | }
170 | }
171 |
172 | public function getUser(){
173 | if(is_object($this->user)){
174 | return $this->user;
175 | } else {
176 | throw new Exception("User not authentificated");
177 | }
178 | }
179 |
180 | }
181 | ?>
182 |
--------------------------------------------------------------------------------
/class/Token.class.php:
--------------------------------------------------------------------------------
1 | exec("insert into token (type,consumer_id,token,token_secret,callback_url) values (1,".$consumer->getId().",'".$token."','".$tokensecret."','".$callback."') ");
20 | }
21 |
22 | public static function findByToken($token){
23 | $ret = null;
24 | $pdo = Db::singleton();
25 | $find = $pdo->query("select id from token where token = '".$token."'");
26 | if($find->rowCount()==1){
27 | $find = $find->fetch();
28 | $request_token = new Token($find['id']);
29 | $ret = $request_token;
30 | }
31 | return $ret;
32 | }
33 |
34 |
35 | public function __construct($id=0){
36 | $this->pdo = Db::singleton();
37 | if($id != 0){
38 | $this->id = $id;
39 | $this->load();
40 | }
41 | }
42 |
43 | private function load(){
44 | $info = $this->pdo->query("select * from token where id = ".$this->id)->fetch();
45 | $this->token = $info['token'];
46 | $this->type = $info['type'];
47 | $this->token_secret = $info['token_secret'];
48 | $this->consumer = new Consumer($info['consumer_id']);
49 | $this->callback = $info['callback_url'];
50 | $this->verifier = $info['verifier'];
51 | if($info['user_id'] != 0){
52 | $this->user = new User($info['user_id']);
53 | } else {
54 | $this->user = 0;
55 | }
56 | }
57 |
58 | public function changeToAccessToken($token,$secret){
59 | if($this->isRequest()){
60 | $this->pdo->exec("update token set type = 2, verifier = '', callback_url = '', token = '".$token."', token_secret = '".$secret."' where id = ".$this->id);
61 | return true;
62 | } else {
63 | return false;
64 | }
65 | }
66 |
67 | /* some setters */
68 |
69 | public function setVerifier($verifier){
70 | $this->pdo->exec("update token set verifier = '".$verifier."' where id = ".$this->id);
71 | $this->verifier = $verifier;
72 | }
73 |
74 | public function setUser(IUser $user){
75 | $this->pdo->exec("update token set user_id = '".$user->getId()."' where id = ".$this->id);
76 | $this->user = $user;
77 | }
78 |
79 | /* some getters */
80 |
81 | public function isRequest(){
82 | return $this->type == 1;
83 | }
84 |
85 | public function isAccess(){
86 | return !$this->isRequest();
87 | }
88 |
89 | public function getCallback(){
90 | return $this->callback;
91 | }
92 |
93 | public function getVerifier(){
94 | return $this->verifier;
95 | }
96 |
97 | public function getType(){
98 | return $this->type;
99 | }
100 |
101 | public function getSecret(){
102 | return $this->token_secret;
103 | }
104 |
105 | public function getUser(){
106 | return $this->user;
107 | }
108 |
109 | }
110 | ?>
--------------------------------------------------------------------------------
/class/User.class.php:
--------------------------------------------------------------------------------
1 |
2 | require(dirname(__FILE__)."/../interfaces/IUser.php");
3 |
4 | class User implements IUser {
5 |
6 | private $id;
7 | private $login;
8 | private $pdo;
9 |
10 | /* bogus function to mimic authentification */
11 | public static function exist($login){
12 | $pdo = Db::singleton();
13 | $check = $pdo->query("select id from user where login = '".$login."'");
14 | if($check->rowCount()==1){
15 | $check = $check->fetch();
16 | return new User($check['id']);
17 | } else {
18 | return null;
19 | }
20 | }
21 |
22 | public function __construct($id = 0){
23 | $this->pdo = Db::singleton();
24 | if($id != 0){
25 | $this->id = $id;
26 | $this->load();
27 | }
28 | }
29 |
30 | private function load(){
31 | $info = $this->pdo->query("select * from user where id = ".$this->id)->fetch();
32 | $this->login = $info['login'];
33 | }
34 |
35 | public function getId(){
36 | return $this->id;
37 | }
38 |
39 | public function getLogin(){
40 | return $this->login;
41 | }
42 | }
--------------------------------------------------------------------------------
/client/apicall.php:
--------------------------------------------------------------------------------
1 | enableDebug();
6 | $oauth_client->setToken($_POST['token'],$_POST['token_secret']);
7 | $oauth_client->fetch("http://localhost/OAuthProviderExample/oauth/api/user");
8 | echo "API RESULT : ".$oauth_client->getLastResponse();
9 | } catch (OAuthException $E){
10 | echo $E->debugInfo;
11 | }
12 | } else {
13 | ?>
14 |
".print_r($E->debugInfo,true).""; 12 | } 13 | ?> 14 | -------------------------------------------------------------------------------- /interfaces/IConsumer.php: -------------------------------------------------------------------------------- 1 | 31 | -------------------------------------------------------------------------------- /interfaces/IToken.php: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /interfaces/IUser.php: -------------------------------------------------------------------------------- 1 | 11 | -------------------------------------------------------------------------------- /oauth/.htaccess: -------------------------------------------------------------------------------- 1 | Options +FollowSymLinks 2 | RewriteEngine On 3 | RewriteCond %{REQUEST_FILENAME} !-f 4 | RewriteRule ^(.*)$ index.php [QSA,L] 5 | -------------------------------------------------------------------------------- /oauth/index.php: -------------------------------------------------------------------------------- 1 | setRequestTokenQuery(); 10 | $provider->checkRequest(); 11 | echo $provider->generateRequestToken(); 12 | } else if(strstr($_SERVER['REQUEST_URI'],"access_token")){ 13 | $provider->checkRequest(); 14 | echo $provider->generateAccessToken(); 15 | } else if(strstr($_SERVER['REQUEST_URI'],"create_consumer")){ 16 | $consumer = Provider::createConsumer(); 17 | ?> 18 |