How to write a complete OAuth Provider in PHP5
Today I’m going to talk about a subject that doesn’t have a lot of coverage on the web.
There is a lot of tutorials about how to use OAuth authentication for twitter services or google & such but there is not a lot of information on how to actually make your own oauth provider.
Now if you are reading this post you probably allready know why Oauth is good and what his purpose is but you can check out some info here.
On this post I’m going to use an basic example case and we will go from nothing to actually handling api calls.
You can download the full source code of a working provider from here. It includes the provider described here as well as a basic client to help you test it out…
Prerequisites
For this entire post I’m going to use the official php oauth library. But you first have to install it from pecl.
At the time i’m writing this article the library at version 1.0 as a bug in the provider class so unless there is now a version 1.1 you’ll have to compile from svn
Dont worry it’s very easy.
sudo apt-get install subversion make php-pear php5-dev libpcre3-dev mkdir oauthsvn cd oauthsvn svn export http://svn.php.net/repository/pecl/oauth/trunk/ cd trunk phpize ./configure make sudo make install sudo nano /etc/php5/apache2/php.ini # add extension=oauth.so at the end of the file sudo /etc/init.d/apache2 restart
Now if version 1.1 is available you can just do
sudo apt-get install php-pear php5-dev libpcre3-dev sudo pecl install oauth sudo nano /etc/php5/apache2/php.ini # add extension=oauth.so at the end of the file sudo /etc/init.d/apache2 restart
Our example
Summary
To start I’m going to try to sumarize what our provider should be able to do
- Generate a request token
- Authenticate a user
- Generate a access token
- Handle a basic API call
Now I’m going to explain in plain (bad) english how it works
The client gets a consumer_key & consumer_secret from you ( this is done only once )
When the client wants to get login credidential for a user, they ask the provider for a request token and they specify a callback url
the provider handles the request and if everything is in order returns a token & a token_secret
The client can then redirect the user to the provider login form with the token (oauth/login?oauth_token=xxxx)
If the user authenticates on our server we generate a verifier (associated with the request token) and redirect the user to the callback url specified
in the request token request (callbackurl?oauth_token=xxxx&oauth_verifier=yyyy)
Now the the client ask for an access token with the oauth_token, oauth_secret & verifier
If everything is correct, the provider generates an access token associated with a user & a consumer.
Please note that this tutorial covers only the provider part !
First of all Let’s explain our DB schema.
You can find a sql file here
user table
| Collumn | Type |
|---|---|
| id | int , auto_increment |
| login | varchar(50) |
consumer table
| Collumn | Type |
|---|---|
| id | int , auto_increment |
| consumer_key | varchar(250) |
| consumer_secret | varchar(250) |
| active | tinyint(1) |
consumer_nonce table
| Collumn | Type |
|---|---|
| id | int , auto_increment |
| consumer_id | int references consumer.id |
| timestamp | bigint |
| nonce | varchar(250) |
token table
| Collumn | Type |
|---|---|
| id | int , auto_increment |
| type | int references token_type.id |
| consumer_id | int references consumer.id |
| token | varchar(250) |
| token_secret | varchar(250) |
| callback_url | varchar(250) |
| verifier | varchar(250) |
token_type table
this table is just for reference
1 – Request
2 – Access
| Collumn | Type |
|---|---|
| id | int , auto_increment |
| type | varchar(50) |
Our Objects
Since this is not a tutorial about how to get access data & such I wont give you all the classes but I’ll show you some interface that we will use during this entire tutorial.
It will give you a full overview of what we are doing.
In the source code that I provide you will get actual classes that are not abstract…
Basicly for this provider to work we need 3 objects.
First we need consumers
A consumer is basicly a client that will connect to your provider.
Every consumer needs a consumer_key and a consumer_secret to authenticate to your website.
In this tutorial I added a the field “active” that will give you the power to unable a consumer without actually deleting him.
IConsumer interface
<?php
interface IConsumer{
/* return an instance of a IConsumer or return null on not found */
public static function findByKey($key);
/* Create in the DB a consumer with a given key & secret */
public static function create($key,$secret);
/* Returns if the consumer is active */
public function isActive();
/* Returns the consumer key */
public function getKey();
/* Returns the consumer secret key */
public function getSecretKey();
/* check if nonce exist for a specified consumer */
public function hasNonce($nonce,$timestamp);
/* Add a nonce to the nonce cache */
public function addNonce($nonce);
public function getId();
}
?>
The second object that we need is token
Tokens are unique identifiers issued by the server, there are two kinds of tokens
Request token that are temporary tokens used to initialize the authentification process
and Access token that are token that identify an authentificated user.
If tokens are not clear for you you should probably check out the doc at the oauth website.
A token have the following attributes
id – identifier
type – request or access
token
token_secret
When It’s a request token we store the callback info and the verifier
And once the authentification is done we store the user associated with that access token
IToken interface
<?php
interface IToken{
/* create a request token */
public static function createRequestToken(IConsumer $consumer,$token,$tokensecret,$callback);
/* returns an IToken instance if you can find a token in the db that matches $token otherwhise return false */
public static function findByToken($token);
/* returns true if this is a request token otherwise return false */
public function isRequest();
/* returns true if this is a access token otherwise return false */
public function isAccess();
/* return callback url */
public function getCallback();
/* return verifier */
public function getVerifier();
/* return type (1 for request - 2 for access) */
public function getType();
/* returns the token_secret */
public function getSecret();
/* returns the user associated with the access token */
public function getUser();
/* sets the verifier in the db*/
public function setVerifier($verifier);
/* sets the user in the db*/
public function setUser(IUser $user);
}
?>
And finally we need a User that is authenticated
IUser interface
<?php
interface IUser{
public function getId();
}
?>
The provider
First of all Here is the code and I’ll go thru it just after
<?php
class Provider{
private $oauth;
private $consumer;
private $oauth_error;
private $user;
private $authentification_url = "http://localhost/OAuthProviderExample/oauth/login.php";
public static function createConsumer(){
$key = sha1(OAuthProvider::generateToken(20,true));
$secret = sha1(OAuthProvider::generateToken(20,true));
return Consumer::create($key,$secret);
}
public function __construct(){
/* create our instance */
$this->oauth = new OAuthProvider();
/* setup check functions */
$this->oauth->consumerHandler(array($this,'checkConsumer'));
$this->oauth->timestampNonceHandler(array($this,'checkNonce'));
$this->oauth->tokenHandler(array($this,'checkToken'));
}
/**
* This function check the handlers that we added in the constructor
* and then checks for a valid signature
*/
public function checkRequest(){
/* now that everything is setup we run the checks */
try{
$this->oauth->checkOAuthRequest();
} catch(OAuthException $E){
echo OAuthProvider::reportProblem($E);
$this->oauth_error = true;
}
}
/**
* This function is called when you are requesting a request token
* Basicly it disabled the tokenHandler check and force the oauth_callback parameter
*/
public function setRequestTokenQuery(){
$this->oauth->isRequestTokenEndpoint(true);
$this->oauth->addRequiredParameter("oauth_callback");
}
/**
* This function generates a Request token
* and save it in the db
* then returns the oauth_token, oauth_token_secret & the authentification url
* 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
*/
public function generateRequestToken(){
if($this->oauth_error){
return false;
}
$token = sha1(OAuthProvider::generateToken(20,true));
$token_secret = sha1(OAuthProvider::generateToken(20,true));
$callback = $this->oauth->callback;
Token::createRequestToken($this->consumer, $token, $token_secret, $callback);
return "authentification_url=".$this->authentification_url."&oauth_token=".$token."&oauth_token_secret=".$token_secret."&oauth_callback_confirmed=true";
}
/**
* This function generates a Access token saves it in the DB and return it
* In that process it also removes the request token used to get that access token
*/
public function generateAccesstoken(){
if($this->oauth_error){
return false;
}
$access_token = sha1(OAuthProvider::generateToken(20,true));
$secret = sha1(OAuthProvider::generateToken(20,true));
$token = Token::findByToken($this->oauth->token);
$token->changeToAccessToken($access_token,$secret);
return "oauth_token=".$access_token."&oauth_token_secret=".$secret;
}
/**
* This function generates a verifier and returns it
*/
public function generateVerifier(){
$verifier = sha1(OAuthProvider::generateToken(20,true));
return $verifier;
}
/* handlers */
/**
* This function checks if the consumer exist in the DB and that it is active
* You can modify it at your will but you __HAVE TO__ set $provider->consumer_secret to the right value or the signature will fail
* It's called by OAuthCheckRequest()
* @param $provider
*/
public function checkConsumer($provider){
$return = OAUTH_CONSUMER_KEY_UNKNOWN;
$aConsumer = Consumer::findByKey($provider->consumer_key);
if(is_object($aConsumer)){
if(!$aConsumer->isActive()){
$return = OAUTH_CONSUMER_KEY_REFUSED;
} else {
$this->consumer = $aConsumer;
$provider->consumer_secret = $this->consumer->getSecretKey();
$return = OAUTH_OK;
}
}
return $return;
}
/**
* This function checks the token of the client
* Fails if token not found, or verifier not correct
* Once again you __HAVE TO__ set the $provider->token_secret to the right value or the signature will fail
* It's called by OAuthCheckRequest() unless the client is getting a request token
* @param unknown_type $provider
*/
public function checkToken($provider){
$token = Token::findByToken($provider->token);
if(is_null($token)){ // token not found
return OAUTH_TOKEN_REJECTED;
} elseif($token->getType() == 1 && $token->getVerifier() != $provider->verifier){ // bad verifier for request token
return OAUTH_VERIFIER_INVALID;
} else {
if($token->getType() == 2){
/* if this is an access token we register the user to the provider for use in our api */
$this->user = $token->getUser();
}
$provider->token_secret = $token->getSecret();
return OAUTH_OK;
}
}
/**
* This function check both the timestamp & the nonce
* The timestamp has to be less than 5 minutes ago (this is not oauth protocol so feel free to change that)
* And the nonce has to be unknown for this consumer
* Once everything is OK it saves the nonce in the db
* It's called by OAuthCheckRequest()
* @param $provider
*/
public function checkNonce($provider){
if($this->oauth->timestamp < time() - 5*60){
return OAUTH_BAD_TIMESTAMP;
} elseif($this->consumer->hasNonce($provider->nonce,$this->oauth->timestamp)) {
return OAUTH_BAD_NONCE;
} else {
$this->consumer->addNonce($this->oauth->nonce);
return OAUTH_OK;
}
}
public function getUser(){
if(is_object($this->user)){
return $this->user;
} else {
throw new Exception("User not authentificated");
}
}
}
?>
First of all you can see that we register three handlers in the constructor.
Those methods are very important and your provider wont work without them.
The checkConsumer method makes sure your consumer exist and that he is active.
The checkNonce makes sure that the timestamp of the oauth request is in a acceptable timeframe and that the nonce used has not been used before
And finally the checkToken checks if the token exist and if it’s an access token request verify that the verifier is correct.
To launch the handlers you have to call the checkRequest method, I did not add the checkRequest in the constructor because If the client is asking
for a request token we need to call setRequestTokenQuery() so that the provider wont launch the token handler.
Everything else is pretty straight forward and should be explained via the method comments.
Oauth controller setup
To make things nice we will handle all Oauth request through a front controller.
So first of all we need to create a directory called oauth
Then create a .htaccess file in this directory to redirect all request to our controller.
Options +FollowSymLinks
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^(.*)$ index.php [QSA,L]
For this example I use those three urls as end point
oauth/request_token
oauth/access_token
oauth/create_consumer
Finally I use oauth/api/user to make an api call
now let’s have a look at our controller
oauth/index.php
<?php
function __autoload($name){
require("../class/".$name.".class.php");
}
$provider = new Provider();
if(strstr($_SERVER['REQUEST_URI'],"request_token")){
$provider->setRequestTokenQuery();
$provider->checkRequest();
echo $provider->generateRequestToken();
} else if(strstr($_SERVER['REQUEST_URI'],"access_token")){
$provider->checkRequest();
echo $provider->generateAccessToken();
} else if(strstr($_SERVER['REQUEST_URI'],"create_consumer")){
$consumer = Provider::createConsumer();
?>
<h1>New consumer</h1>
<strong>Key : </strong> <?php echo $consumer->getKey()?><br />
<strong>Secret : </strong> <?php echo $consumer->getSecretKey()?>
<?
} else if(strstr($_SERVER['REQUEST_URI'],"api/user")){
/* this is a basic api call that will return the id of an authenticated user */
$provider->checkRequest();
try {
echo $provider->getUser()->getId();
} catch(Exception $E){
echo $E;
}
}
?>
And our login form
oauth/login.php
<?
function __autoload($name){
require("../class/".$name.".class.php");
}
if(isset($_REQUEST['oauth_token'])){
$request_token = Token::findByToken($_REQUEST['oauth_token']);
if(is_object($request_token)&&$request_token->isRequest()){
if(!isset($_POST['login'])){
?>
<form method=post>
<label>Login : </label><input type="text" name="login" /><br />
<input type="submit" value="Authenticate to this website" />
</form>
<?
} else {
$user = User::exist($_POST['login']);
if(is_object($user)){
$request_token->setVerifier(Provider::generateVerifier($_REQUEST['oauth_token']));
$request_token->setUser($user);
/* this is where we redirect to the callback url */
header("location: ".$request_token->getCallback()."?&oauth_token=".$_REQUEST['oauth_token']."&verifier_token=".$request_token->getVerifier());
} else {
echo "User not found !";
}
}
} else {
echo "The specified token does not exist";
}
} else {
echo "Please specify a oauth_token";
}
?>
This basicly check if the user exist and so generates the verifier & redirect to the callback url
Conclusion
If you prefer to have a working example and go from there please get the source code.
I included a client to help you guys get a good understanding on how it works.
If you need any aditional info or you want to say Hello Leave a comment !
Have fun !

Hello all! I’m just getting started with Oauth Providers and have got some other client api’s working from their example code. I’d like to be abe to provide access to a simple api on my site over oauth. I’ve setup these files on my VPS account, and the database using sql schema, but when I go to the page ../client/index.php page I get :
We have a request token !
Request token :
Request token secret :
to authenticate go _here_
So I click on the ‘here’ link and nothing happens, except the link changes in the address bar to:
http://…/OAuthProviderExample/client/index.php?oauth_token=
I’vegone through the “if they can do it, so can I phase”, but after two days of being stomped I need a little help please
Can someone throw me some training wheels for getting very basic example up and running using this post.
Thanks!
Hi Trey,
I have the same problem.
Its got some \n characters in the $info array in the index file. Must be a bug of some sort.
my quick fix was this:
in client/index.php
$info = $oauth_client->getRequestToken(“http://localhost:8089/oauth/request_token?oauth_callback=http://localhost:8089/client/callback.php”);
//hack cuz some weird shit was happening with the authentification_url array key.
$info2 = array();
foreach ($info as $key => $vagkef)
{
$key = str_replace(“\n”, “”, $key);
$info2[$key] = $vagkef;
}
$info = $info2;
//END HACK
Now i am on the next screen fiddling with the client.. I think i nearly have my system sorted.. I just need to understand the access part.
yes,key is there in database.
I am using key = ‘client_key’
and secret = ‘client_secret’
I am getting consumer_key_unknown error. previously it was working but suddenly it started showing errors .I am passing correct key and secret.
[headers_recv] => HTTP/1.1 401 Unauthorized
oauth_problem=consumer_key_unknown&oauth_token=c800eac69f4dbcd9c461d5dd928f846362701ab0&oauth_token_secret=5dca5cd71af3d1ce62587b6630917b44d7fa353c&oauth_callback_confirmed=true&authentification_url=http://localhost/oAuth/code/server/login.php
Check your database to make sure the key is still there.
Hi again, Christophe!
I’ve been using an OAuth provider code based on yours for a while now. My app is almost deploying, so I made some deployment trials to a Ubuntu server which didn’t go that well.
I develop using Windows and the code worked just fine. When I ran my app on Ubuntu though, I surprised myself that the OAuthProvider::generateToken with $strong=true is VERY VERY slow. Reading at the PHP documentation I see that setting $strong as true the method will use /dev/random instead of /dev/urandom. Also, I read that changing $strong to true is useless on Windows. I’m a newbie UNIX user and couldn’t get it fixed nor understand the differences between those two magic files. Do you know what is probably happening and if is there anything I can do? Or is the /dev/random slow by its nature?
Thank you,
Leonardo.
Hello Leonardo,
I had the exact same issue, apparently /dev/random is sometimes slow because there is not enough “entropy” available. you can change the value to false and that should fix your problem.
I used true because /dev/random is supposed to be more random then urandom but for oauth it’s not that important.
Thank you!
Setting to false solved the problem
Have a nice week,
Leonardo.
Really helpful article.
Do we know if the provider in pecl oauth is 1.0 or 1.0a ?
Thanks
Brian
Hi Sir,
how install oauth without svn on our window site in local host.
thanks
Radhey
Hello,
I have no idea on how to do that since I havent used windows in years
Good luck
So, how to used your example on our localhost, i am unable to find it solution any other solution to configure your example.
thank very much
Maybe you’ll find what you need here http://downloads.php.net/pierre/
I am find this error on our localhost
Warning: require(../class/OAuthProvider.class.php) [function.require]: failed to open stream: No such file or directory.
i already configure php_oauth.dll in php.ini file
Thanks.
Any plan to make an oauth2 version Christ? Seem like all the big guys now switched to oauth2 which seems to be much simpler to implement (for the clients)
I’ll have to check that, but last time I looked the official specs for the v2 were not final…
Hey, this tutorial was really helpful for me to get started with writing our OAuth provider, but wanted to give a heads up to anyone using some of the standard libraries such as the MPOAuthConnection library for Objective C.
These expect the verifier to be named oauth_verifier (as per section 2.2 of OAuth specification – http://tools.ietf.org/html/rfc5849#section-2.2 ) rather than “verifier_token” as it appears in the sample code. Might save you a few hours headache wondering why you can get a request token but not an access token.
thanks for you comment, I fixed the code accordingly.
Hi Stuart, how did you do it with MPOauthConnection? I tried it with the Oauth Provider from this tutorial, but it kept giving me oauth_problem: signature_invalid when requesting request token.
@Christophe
As I’m yet getting used to all OAuth specification, I found that excerpt a little confusing so I found that one (via http://oauth.net/core/1.0a/, chapter 8):
“The Consumer SHALL then generate a Nonce value that is unique for all requests with that timestamp. A nonce is a random string, uniquely generated for each request. The nonce allows the Service Provider to verify that a request has never been made before and helps prevent replay attacks when requests are made over a non-secure channel (such as HTTP).”
And “value that is unique for all requests with that timestamp” killed my doubts. BUT again, as I am not entirely sharp with OAuth, I though: well, I’d better ask Christophe then…
Now, changing the subject; about database cleanup, would you agree that it’s safe to remove expired nonces as they wouldn’t be used anyway? Would removing those nonces open a breach to “repeat attacks”? As far as I understood with the checkNonce method, we check if consumer-sent `timestamp` is “synchronized” with server’s time and if so we check if the sent `nonce` exists (according to sent `timestamp`) and if it does we don’t proceed. So, if an expired nonce be removed the script would proceed which is a problem, or isn’t?
Here’s how the modified script is:
public function checkNonce($provider) {
if ($this->oauth->timestamp oauth->timestamp > (time() + 5*60)){ //Check for consumer/provider time synchronization
return OAUTH_BAD_TIMESTAMP;
}
elseif ($this->consumer->hasNonce($provider->nonce, $this->oauth->timestamp)) {
return OAUTH_BAD_NONCE;
}
else {
$this->consumer->addNonce($this->oauth->nonce, $this->oauth->timestamp); //Insert a new `nonce` to the DB
return OAUTH_OK;
}
}
This might be useful: http://oauth.net/advisories/2009-1/
Well as you can see in the checkNonce I begin by checking that the timestamp is not older than 5 minutes. Since It would then fail I believe it’s safe to remove the nonce older than 5 minutes… I read somewhere that big providers such as twitter dont even bother to store them… dunno if it’s true thought but apparently when you start to load balance it can be an issue because of the server sync…
@Leods I updated the code on github. I also added a register to the comment feature on the blog so you dont have to F5 to death
I’ve just checked the committed code; and I have some thoughts…
In the `addNonce` method I add the timestamp based on consumer’s timestamp, instead using the servers one. Cause through `hasNonce` we also based on consumers’s timestamp. I don’t know if that makes any great difference but it seems more “semantic” to me.
If you decide not to change that, I would recommend using in `addNonce` query the mysql function “NOW()” or in case DB field is INT (instead of TIMESTAMP) UNIX_TIMESTAMP(NOW()).
I’m not sure about this, IMO since the timestamp can be set via the client I rather set it safely by the provider.
As for now() instead of php time() I think time() is better since it would be easier to sync only the php server instead of the mysql one that could on another server…
Christophe,
Shouldn’t consumer::hasNonce() method check for existence of a nonce based on consumer_id AND timestamp? I mean, shouldn’t be considered an invalid nonce an existent nonce for a specific timestamp?
Well according to the RFC
If I understand correctly you are right. I’m trying to think of a reason why I did it like that but I can’t.
I’ll try to update the code accordingly soon.
Christophe,
Could you explain why you put in Consumer.class.php line 19 “This is not safe!”?
$info = $pdo->query(“select id from consumer where consumer_key = ‘”.$key.”‘”); // this is not safe !
Thank you.
This query could be used to do some sql injection because $key is not escaped.
Simply use $pdo->quote for example to secure it or use a prepared statement…
i think this 2
Thanks
Can you guide me how to install oauth extension on wamp server
Hi
I have downlopad the code and put in wamp server
it says OAuthProvider class is missing . How can i resolve this problem?
Please help me
did you install the oauth extension ?
Dear Christophe,
I don’t understand how the client would “know” the token_secret…
I’m new to the OAuth authentication method but as far as I understand it the token_secret is generated using an algorithm that both client and sever know; in that way it doesn’t need to be (and can’t be) sent through HTTP from the provider.
Your client example asks for the token_secret through a form and you wrote in it “This is not passed by url, a real client would have stored this somewhere, you can get it from the db”. So I get the value from my db and POST: it works perfectly. What I want though, is to skip the form (what would happen in a real implementation) and access the API sending the token_secret TO the provider.
You’ve set in Provider class, token_secret = sha1(OAuthProvider::generateToken(20,true)); which is just a random number, right? In that way is not possible (at least I don’t how) to the client “guess” the token_secret, is it?
I’m sorry if all of above is confusing, but even though I’m trying hard to understand the OAuth flow I still haven’t understood it entirely.
I would really appreciate it some of your help.
Thank you in advance,
Leonardo.
@leonardo
the token secret is passed once from the provider to the client when the client asks for the access token with the verifier.
https://github.com/djpate/OAuthProviderExample/blob/master/client/callback.php
I’m not sure if that answers your question ?
Regards
Nice article. Do you mind writing another article or tutorial about how to implement REST with OAUTH using PHP ? Thanks
In the apicall.php,
$oauth_client->setToken($_POST['token'],$_POST['token_secret']);
if I pass the wrong token_secret but the correct token, there is no exception thrown.
echo “API RESULT : “.$oauth_client->getLastResponse(); prints Array with no values. So how can the client know that it passed an invalid token_secret?
Ok well I just checked the OAuth documentation And apparently the token secret is used to encrypt the signature.
In the function that I gave you earlier, The provider sets the token secret so that the provider can encrypt the signature & verify it.
This part is done by the oauth extension so I’m not sure why It doesnt give you an Exception but I’ll look into it…
If I pass the correct token with a wrong access key, the provider does not throw any exception? As per your git hub page, the client should receive a OAUTH_TOKEN_REJECTED response. In the example api call, i just receive an empty array but no indication of the wrong access key.
What do you call the access key ?
The token verification is done here https://github.com/djpate/OAuthProviderExample/blob/master/class/Provider.class.php#L135
the client use the secret to generate the oauth_signature.
the provider set the token secret here
$provider->token_secret = $token->getSecret();
Once the secret is set, it generates a signature & verify that it matches the signature provided by the client…
Sorry, I don’t understand. In the api call, we use
$oauth_client->setToken($_POST['token'],$_POST['token_secret']);
This token_secret is not passed by the client to the server?
Why is this token secret not checked whether its matching with our value in db table?
Since the secret is never sent by the client we verify the secret via the signature verification.
That’s why we set the secret in the tokenHandler function. It’s always check unless it’s the request token endpoint.
Hi,
Great tutorial for learning about implementing ouath.
A correction,
public function generateVerifier should be declared as static.
Also after getting an access token and a consumer makes an api call where is the access token checked for validity?
In check token function,
elseif($token->getType() == 1 && $token->getVerifier() != $provider->verifier){ // bad verifier for request token
return OAUTH_VERIFIER_INVALID;
}
else {
if($token->getType() == 2){
/* if this is an access token we register the user to the provider for use in our api */
$this->user = $token->getUser();
}
$provider->token_secret = $token->getSecret();
The token secret is never checked for validity or am I missing something?
Thanks a lot for the tutorial
Thanks a lot for the tutorial, anyway!
I guess you will have to parse the request_uri, maybe you could ask on stackoverflow but as of my knowledge I wouldn’t know… Sorry
When fetching the resource from the client if you add the extra parameters in the fetch() method it corrects the problem:
$oauth->fetch(“http://domain.com/items/test-field-val”, array(‘field’=>’test-field-val’));
Unfortunately, the point is for the URL to appear as if it were a static resource and the consumer shouldn’t have to specify the field separately as it’s already in the URL …
Sure. Using the second rewrite rule (and resulting in the signature error), print_r($_REQUEST) and $_SERVER['REQUEST_URI'] yield respectively:
Array( [field] => test-field-val )
/items/test-field-val
While the first rewrite rule (that doesn’t give an error) has an empty $_REQUEST array and a REQUEST_URI of:
/items/test-field-val
This makes me think the problem is that when I run the rewrite rule to pass the field value as a member of the $_REQUEST array it’s not getting concatenated to the base string used to create the signature, but I don’t know how to custom generate the base string before it gets signed.
Of course, if I can’t make that work I could just parse the REQUEST_URI variable to pull out the values I want from a front controller, but this is also a learning experience so I’d like to figure it out.
Thanks for your time!
This question may be outside the scope of this article but …
I’ve created an implementation of your example and it works smoothly. When I try to introduce some apache rewrites to make my api more RESTful I have problems.
The first rule listed below works correctly, but if I try to redirect an oauth request to a pretty URL using the second rule I get a “Signatures do not match” error back.
RewriteRule ^items items.php [QSA,L]
RewriteRule ^items/([^/\.]+)?$ items.php?field=$1 [QSA,L]
I imagine this is because it’s changing the string that’s being signed but I’m not sure how to go about fixing that. Any ideas?
Can you do an print_r($_REQUEST); in items.php so we can check what’s been passed
Thanks for your remark, there was actually a bug since you don’t need the token to generate the verifier. I fixed the source accordingly.
I’ve been working through this all evening, so first of all, thank you for putting it out there!
My question:
In line 20 of oauth/login.php you pass an argument to Provider::generateVerifier() like so:
Provider::generateVerifier($_REQUEST['oauth_token'])
But as it’s specified in line 97 of class/Provider.class.php, generateVerifier() takes no arguments. What’s to be done with the oauth_token? should the verifier be created using $_REQUEST['oauth_token'] as a salt of some kind? Or can it just be randomly generated?
Also, should generateVerifier() technically be declared static if we’re using it this way?
Thanks in advance and thanks again for your efforts!
whats the difference beetween consumer and user in the db??
Dude I think your need to read again the Oauth doc to make sure you know what you are doing before using my provider.
To give you a concrete example, if i added a facebook connect to my blog.
You would be the user, djpate.com would be the consumer & facebook the provider.
i have it installed but nothing…. this is my client code:
enableDebug();
try {
$info = $oauth_client->getRequestToken(“http://172.16.88.128/mobu/oauth/request_token?oauth_callback=http://127.0.0.1/mobu/client/callback.php”);
echo “We have a request token !”;
echo “Request token : “.$info['oauth_token'].”";
echo “Request token secret : “.$info['oauth_token_secret'].”";
echo “to authenticate go here“;
} catch(OAuthException $E){
echo “”.print_r($E->debugInfo,true).”";
}
?>
chriss, i tried an Oauth client from http://oauth.googlecode.com/svn/code/php/example/client.php
and checked the endpoints ant they worked!! but when i try with your client, it seems that doesn’t work…
can you explain me this command?
“$oauth_client = new Oauth(“key”,”secret”);”
in client/index.php
txs brou
This line just create an oauth client (http://www.php.net/manual/en/oauth.construct.php). you need to install pecl oauth also on your client machine…
request_token.php? where is this file? do i have to create it? the same for the other two.. access_token and create_consumer…
this urls endpoints are in the pecl libs??? im kind of lost with those three urls….
For this example I use those three urls as end point
oauth/request_token
oauth/access_token
oauth/create_consumer
You dont have to create them, It uses a url rewrite to redirect to oauth/index.php
Make sure you enabled the rewrite module on your apache conf
brou i got a virtual machine, installed ubuntu server on it, and from my local machime im trying to use the virtual machine as a server and my local as a client… regarding your source code… what should be my next step? all files go to the server except for the client folder?
Yeah install oauth 1.1.0 from pecl, setup mysql & load the db schema & copy all files except the client folder.
i started back from scratch, installed php5, apache, mysql, pecl etc… lets see what happpens maybe that was my problem…
brou i check your page every 15 minutes…. what happend with the coverage?? please help us!!!
Stay tuned, it will be posted tomorow
i wuold really aprecciated!!! thanks brou!!!
hi again, is there an step by step guide for your code?
i have all the libs and requirements, but i dont know which one should be my first step….
I’m going to write something out tonight or tomorrow… Apparently this tutorial has been linked from the official documentation and should get some coverage…
when i go to /oauth/login.php
i get this message… “Please specify a oauth_token”
i dont get it… please help me
As I said in my previous reply, you need to get a Request token (client/index.php) before going to the oauth/login.php. Once you have the request token you can go to oauth/login.php?oauth_token=xxx
dude need some assistant, i know im pretty close but not there yet…
im trying to integrate oauth to a api that im creating in php…
im stuck here…”Please specify a oauth_token” where does it has to be specified??????
thanks in advance!!
Before going to the authentification form you need to get a request token. By going to /client/index.php then click and the link below and you’ll see that there is an extra parameter called oauth_token…
I’m not sure If that is where you are stuck ?
Dude, you are my new hero. I’ve been hunting for something like this for MONTHS. Thanks so much!
Glad you like it !
Very cool thanks for the post