Make Oauth API calls with existing Access Token and Access Token Secret - php

I am using the Lusitanian PHP Oauth library (https://github.com/Lusitanian/PHPoAuthLib).
After the user gets authorized in my application, i have received values of Access Token and Access Token Secret. Now with these values, i would like to make authenticated calls to API. How can i make the calls with the values of Access Token, Access Token Secret, along with the values of Consumer Key and Consumer Secret? I don't want to get the user authorized every time, to make API calls for him. Does anyone have an idea ?
My request goes like this:
$result = json_decode( $service->request( '/users/getDetails' ), true
);
I have tried the REST Client of Firefox and Advanced REST Client of Chrome, that perform OAuth calls successfully, with just the values of Access Token, Access Token Secret, Consumer Key and Consumer Secret.
Similarly, i would like to perform the OAuth calls from my PHP code. The library which i am using, depends on Session to store these values (which requires the user to login each time) and build the Authorization header and signature. Is there a way i can build the Signature and Authorization header from my end manually and make the OAuth calls ?

Finally, i have tweaked the functionality of reusing the access tokens.
I am fetching token from a config php file, after i store the token in it.
The token can also be stored in a local PHP session and read from it.
The code for storing token is in Service/AbstractService.php:
$this->storage->storeAccessToken($this->service(), $token);
You can modify it like the following, to store the token in a session variable:
if(!isset($_SESSION['access_token'])) {
$token = new StdOAuth1Token();
$token->setRequestToken($access_token);
$token->setRequestTokenSecret($access_token_secret);
$token->setAccessToken($access_token);
$token->setAccessTokenSecret($access_token_secret);
$token->setEndOfLife(StdOAuth1Token::EOL_NEVER_EXPIRES);
$_SESSION['access_token'] = serialize($token);
}
Then when making a request to API, you can modify the code in request() function to use token from your session:
Change:
$token = $this->storage->retrieveAccessToken($this->service());
To:
$token = unserialize($_SESSION['access_token']);
This way, i could use custom PHP sessions to store and retrieve access tokens. You can also use Database or a text file to store and retrieve the tokens. It works! Hope it would be useful for someone.

Related

Storing the Google OAuth Authorization Token in Database

I am building a portal where multiple users can log in to their multiple Gmail accounts. I have successfully retrieved the token value, However, I want to store that in my database but I am unable to store it.
Below is the code I am using:
function mInititalize(){
$client = new Google_Client();
$client->addScope('https://www.googleapis.com/auth/plus.login https://www.googleapis.com/auth/userinfo.email https://mail.google.com/');
$client->setClientId(Config('gmail.client_id'));
$client->setClientSecret(Config('gmail.client_secret'));
$client->setRedirectUri('http://localhost:81'.Config('gmail.redirect_url'));
$loginURL = $client->createAuthUrl();
return redirect($loginURL);
}
After Redirection or user login
function mGetToken(){
$token = $client->fetchAccessTokenWithAuthCode( 'code'); // here i get the 'code' from login URL
I pass this code to get token I successfully get token
$oAuth = new Google_Service_Oauth2( $client);
$userData = $oAuth->userinfo_v2_me->get(); // get current user detail
}
I want to store $token value in database, but I am getting error message
>Serialization of 'Closure' is not allowed
Please anyone help me to solve this issue. Thanks.
I would suggest storing OAuth credential information for the Google API, not in your database, but through the API itself. If you're intending to use it any authentication manner, you'll run into problems, as the docs state:
Access tokens periodically expire and become invalid credentials for a related API request. Google Identity Platform: Using OAuth 2.0 for Web Server Applications
But, the same docs also show a way that you can set or retrieve the token natively within the API. Since it's data relating to google's auth'ing process, and since it might go stale if you store it, it seems best to just let them handle it and work with the API. The same source:
If you need to apply an access token to a new Google_Client object—for example, if you stored the access token in a user session—use the setAccessToken method:
$client->setAccessToken($access_token);
$client->getAccessToken();

How can I re-acquire a Shopify OAuth access token for a store that has previously installed my application?

I requested authorization for a public application to be able to access store data via the Shopify API.
The store successfully authorized my application via an authorization request URL such as
https://some-store.myshopify.com/admin/oauth/authorize?client_id=123abc&scope=read_inventory%2Cread_products&redirect_uri=http%3A%2F%mysite.com%2Fauth.php&state=123456
and the response was passed back to my application. This response (containing the code that can be exchanged for a permanent access token) was mishandled by my application (an error on the page meant that the access token was not stored).
Everything I read regarding requesting these tokens involves authorization by the store - but given the store has already authorized my application, passed back the code and that code has already successfully been exchanged for a token: is there a way my application can request that same token or a fresh one using my API keys given that the application is already authorized?
The only method I currently can find for requesting a token requires starting back at the beginning and fetching a code for exchange etc.
I working in PHP and using Luke Towers' php shopify wrapper
This stage was completed successfully:
function check_authorization_attempt()
{
$data = $_GET;
$api = new Shopify($data['shop'], [
'api_key' => '123',
'secret' => '456',
]);
$storedAttempt = null;
$attempts = json_decode(file_get_contents('authattempts.json'));
foreach ($attempts as $attempt) {
if ($attempt->shop === $data['shop']) {
$storedAttempt = $attempt;
break;
}
}
return $api->authorizeApplication($storedAttempt->nonce, $data);
}
$response = check_authorization_attempt();
and I would have been able to read the access token from :
$access_token = $response->access_token;
But this was the stage at which my application hit an error in accessing a database in which to write said token.
I cannot repeat it without repeating the auth request because the data in $_GET that's passed to this function comes from Shopify's response to the shop owner authorizing the access, and includes amoung other things the code for exchange.
You have to re-ask for authorization. It is no one's fault but yours that your persistence layer code was incorrect. So there is nothing you can do to change that. Ensure your code works. Since the client has no token in your App persistence layer, your App will retry the authorization token exchange. They do not have to delete your App first. So basically, the next time your client tries to use the App, YES they will asked to approve it, but who cares, they will, and you'll get a good auth token to store. You have fixed your code (right), so that will work. You are one step closer to glory.
Shopify does return the Permanent Access Token, but the ACCESS_MODE must be "Offline" for the token to be permanent.
With ACCESS_MODE offline, your app receives the permanent access token
to make requests whenever you want, without the user's permission.
Documentation:
https://shopify.dev/tutorials/authenticate-with-oauth#step-2-ask-for-permission
https://shopify.dev/concepts/about-apis/authentication#api-access-modes

PHP authentication with JWT

I'm creating a sort of 'social network'. Now I'm creating the authentication part. Today I learned about JSON Web Tokens.
1) I read that JWT's are safe to use, because the are signed with a secret key. But then I found some tools online like https://jwt.io. I tried to build some JWT tokens with PHP using firebase/php-jwt. The tools like jwt.io can extract the data I put in the JWT (like user ID). How can this be safe? Can't someone just create a new JWT using the old one but with a different user ID?
An example: I created the following token:
eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpc3MiOiJNeUFQIiwiaWF0IjoxNTE2NTYzMTM0LCJleHAiOjE1MTY1NjQzNDAsImF1ZCI6Ind3dy5leGFtcGxlLmNvbSIsInN1YiI6ImFkbWluQGV4YW1wbGUuY29tIiwibmFtZSI6IkpvaG4gRG9lIiwiYWRtaW4iOiJmYWxzZSJ9.dCtYVpFXhoQmzOdX_dW1yFHEcZ9aZ1I9MC33lJGapvY
If you paste this token in jwt.io, you'll see the payload is "name: John Doe" and "admin: false". Isn't this unsafe? Or is it safe because you NEED the secret key to recreate a JWT.
Off the record: You cannot store senstive information in a JWT I guess...
2) How to "login" a user using PHP and JWT's? I created a quick demo, I'm not sure the code "works" but I guess you'll see what I mean.
if (isset($_POST['submit'])) {
$user = $_POST['user'];
$pass = $_POST['pass'];
if($user = 'my_username' && $password == 'my_password') {
// user is logged in
// create a JWT here
} else {
// wrong credentials!
}
}
Now, the question/problem is: how to store this token? In a cookie? In a session? Using HTML5's localStorage? What is the safest way to do this?
And secondly: how to authenticate the user? I would do it like this:
// my secret key
$secret = 'MY_SECRET_KEY';
// decode the token
$token = JWT::decode($token, $secret, array('HS256'));
// what to do here?
Can you match this token with some data in a database or something?
1) The JWT token is not encrypted, so the data inside it can be easily read. However, it contains a signature that can be validated only with the secret key you have set when creating the token. You can check the signature to see that the token has not been tampered with.
2) The token can be stored anywhere, since it's so small. Just remember that the token can be easily read, but not altered. Don't store any sensitive data in the tokens.
When checking the token, the important things to check are the signature and the exp time to see that the token is still valid. A well-constructed token doesn't need full database validation, but rather just check that the user's privileges haven't been changed since issuing the token, and if they have, recreate the token with the updated data or force the user to log in again.

Change scope while issuing new access token when client sends valid refresh token

I am using php oauth2 library from this github repo.
PHP oauth2 library
Whenever i send a refresh token, I receive new access token with old scopes.
But i want to change the scopes returned with new access token.
When i first generate a token using user credentials grant type, I get the supported scopes for the user and store them this way.
$defaultScope = implode(" ", $scopes);$memory = new OAuth2\Storage\Memory(array('default_scope' =>$defaultScope));
$scopeUtil = new OAuth2\Scope($memory);
$this->server->setScopeUtil($scopeUtil);
$this->server->handleTokenRequest(OAuth2\Request::createFromGlobals())->send();
where $scopes is an array
for example $scopes=array("ADDUSER","EDITUSER","EDITROLE");
similarly , if i send refresh token using refresh_token grant type and run this with modified $scopes
for example $scopes=array("ADDUSER", "EDITROLE");
$defaultScope = implode(" ", $scopes);$memory = new OAuth2\Storage\Memory(array('default_scope' =>$defaultScope));
$scopeUtil = new OAuth2\Scope($memory);
$this->server->setScopeUtil($scopeUtil);
$this->server->handleTokenRequest(OAuth2\Request::createFromGlobals())->send();
I receive same old scopes("ADDUSER EDITUSER EDITROLE") which were set when new access token generated using user credentials grant type.
SO is there a way to change scopes when new access token is generated using refresh token ?
or am i doing something wrong here?
A Client can "down-scope" when it asks for a new access token in the refresh token grant, see the documentation around scope in the spec here: https://www.rfc-editor.org/rfc/rfc6749#section-6 Yet your Authorization server may or may not support that.

How to implement 'Token Based Authentication' securely for accessing the website's resources(i.e. functions and data) that is developed in PHPFox?

I want to use methods and resources from the code of a website which is developed in PHPFox.
Basically, I'll receive request from iPhone/Android, I'll get the request and pass to the respective function from the PHPFox code, take the response from that function and return it back to the device.
For this purpose I've developed REST APIs using Slim framework.
But the major blocker I'm facing currently is in accessing the resources(i.e. functions and data) of PHPFox website.
I'm not understanding how should I authenticate the user using 'Token Based Authentication' in order to access the website's resources.
If someone could guide me in proper direction with some useful working example it would be really helpful for me.
N.B. : The proposed implementation of 'Token Based Authentication' should be very secure and fast in speed. The security should not be compromised in any way.
Following is the code I tried on my own but I don't know whether it's right or wrong. Is my approach correct or wrong. Please someone analyse it and let me know your feedback on it.
To create a token i use this function which takes as parameters, the user's data
define('SECRET_KEY', "fakesecretkey");
function createToken($data)
{
/* Create a part of token using secretKey and other stuff */
$tokenGeneric = SECRET_KEY.$_SERVER["SERVER_NAME"]; // It can be 'stronger' of course
/* Encoding token */
$token = hash('sha256', $tokenGeneric.$data);
return array('token' => $token, 'userData' => $data);
}
So a user can authentified himself and receive an array which contains a token (genericPart + his data, encoded), and hisData not encoded :
function auth($login, $password)
{
// we check user. For instance, it's ok, and we get his ID and his role.
$userID = 1;
$userRole = "admin";
// Concatenating data with TIME
$data = time()."_".$userID."-".$userRole;
$token = createToken($data);
echo json_encode($token);
}
Then the user can send me his token + his un-encoded data in order to check :
define('VALIDITY_TIME', 3600);
function checkToken($receivedToken, $receivedData)
{
/* Recreate the generic part of token using secretKey and other stuff */
$tokenGeneric = SECRET_KEY.$_SERVER["SERVER_NAME"];
// We create a token which should match
$token = hash('sha256', $tokenGeneric.$receivedData);
// We check if token is ok !
if ($receivedToken != $token)
{
echo 'wrong Token !';
return false;
}
list($tokenDate, $userData) = explode("_", $receivedData);
// here we compare tokenDate with current time using VALIDITY_TIME to check if the token is expired
// if token expired we return false
// otherwise it's ok and we return a new token
return createToken(time()."#".$userData);
}
$check = checkToken($_GET['token'], $_GET['data']);
if ($check !== false)
echo json_encode(array("secureData" => "Oo")); // And we add the new token for the next request
Am I right?
Thanks.
1st you should understand what's token based authentication. It could be explained as below.
The general concept behind a token-based authentication system is
simple. Allow users to enter their username and password in order to
obtain a token which allows them to fetch a specific resource -
without using their username and password. Once their token has been
obtained, the user can offer the token - which offers access to a
specific resource for a time period - to the remote site.
Read more
Now let's see what are the steps of implementing it in your REST web service.
It will use the following flow of control:
The user provides a username and password in the login form and clicks Log In.
After a request is made, validate the user on the backend by querying in the database. If the request is valid, create a token by
using the user information fetched from the database, and then return
that information in the response header so that we can store the token
browser in local storage.
Provide token information in every request header for accessing restricted endpoints in the application.
If the token fetched from the request header information is valid, let the user access the specified end point, and respond with JSON or
XML.
See the image below for the flow of control
You might be wondering what's a JWT
JWT stands for JSON Web Token and is a token format used in
authorization headers. This token helps you to design communication
between two systems in a secure way. Let's rephrase JWT as the "bearer
token" for the purposes of this tutorial. A bearer token consists of
three parts: header, payload, and signature.
The header is the part of the token that keeps the token type and encryption method, encoded in base64.
The payload includes the information. You can put any kind of data like user info, product info and so on, all of which is also stored in
base64 encoding.
The signature consists of combinations of the header, payload, and secret key. The secret key must be kept securely on the server-side.
You can see the JWT schema and an example token below;
You do not need to implement the bearer token generator as you can use php-jwt.
Hope the above explains your confusion. if you come across any issues implementing token based authentication let me know. I can help you.

Categories