Login by multiple user accounts when using JSON Web Token - authentication

I am using JSON Web Token to authenticate the user in my application. Using https://jwt.io documentation, I use the jwt token to authenticate the user.
$tokenData = array(
"jti" => $tokenId,
"iat" => $issuedAt,
"exp" => $expire,
"user" => $user
);
$jwt = JWT::encode($tokenData, $secretKey, 'HS512');
But the problem is when one user can not login from multiple devices at the same time, it gives an error since the first login token get invaidated. Is there a way to handle this issue. Thanks in advance.

Related

Twitter Ads API error: INSUFFICIENT_USER_AUTHORIZED_PERMISSION. How to solve it?

I am trying to perform a request to the twitter Ads API in my dev environment. I am already registered to get access to this service.
I have received a confirmation e-mail like this:
Your application (ID:12345678) has been approved for the Twitter Ads API program and your organization has been granted a Developer license for Read/Write access. ...
This is why I suppose to have my APP ready to query the Ads API.
Besides that I have information about the APP (tokens and secrets) in the page https://developer.twitter.com/en/apps but I can't find any reference to the account_id, mentioned in the official documentation.
Advertising accounts are registered on ads.twitter.com and identified
in the API by account_id. Advertising accounts link directly to funding
sources and leverage content from one or more Twitter user accounts as
‘promotable users’. Each advertising account can grant permission to
one or more Twitter user accounts. The advertising account, or “current
account,” is represented in nearly every URL executed as an in-line
:account_id parameter.
Following this post I have create the follow code in oder to get access to the Twitter Ads API:
$settings = array(
'oauth_access_token' => env('TWITTER_ACCESS_TOKEN'),
'oauth_access_token_secret' => env('TWITTER_ACCESS_TOKEN_SECRET'),
'consumer_key' => env('TWITTER_CONSUMER_KEY'),
'consumer_secret' => env('TWITTER_CONSUMER_SECRET'),
);
$url = 'https://api.twitter.com/1.1/followers/ids.json';
$getfield = '?screen_name=J7mbo';
$requestMethod = 'GET';
$twitter = new TwitterAPIExchangeService($settings);
$data = $twitter->setGetfield($getfield)
->buildOauth($url, $requestMethod)
->performRequest();
dd($data);
The previous code is working (I am not querying Ads API. But the next one ( querying the Ads Api) is not working:
$url = 'https://ads-api.twitter.com/5/accounts';
$requestMethod = 'GET';
$twitter = new TwitterAPIExchangeService($settings);
$data = $twitter->buildOauth($url, $requestMethod)->performRequest();
dd($data);
{"errors":[{"code":"INSUFFICIENT_USER_AUTHORIZED_PERMISSION","message":"User 2222222222 is not authorized to make this request. Please have them reauthorize with your client application APPNAme."}],"request":{"params":{}}}
What am I missing?
I have found a solution. I don't know if this is the only one but it works.
We must instal Twurl. Twurl is a curl-like application, tailored specifically for the Twitter API.
Install twurl in your system. $ sudo gem install twurl
Set authorization to twurl acceess your twitter APP. $ twurl authorize --consumer-key xxxxx --consumer-secret xxxxx
That is the output for the prevoius command: Go to https://api.twitter.com/oauth/authorize?oauth_consumer_key=xxxx&oauth_nonce=ffff&oauth_signature=bbb&oauth_signature_method=HMAC-SHA1&oauth_timestamp=1556889574&oauth_token=ddd&oauth_version=1.0 and paste in the supplied PIN
Open the browser copy and paste the provided URL https://api. .... version=1.0
You will be redirected to a page asking to confirm the authorization. Confirm it.
You will receive a message: 'You've granted access to APP_Name! Next, return to APP_Name and enter this PIN to complete the authorization process. PIN = 09010101'.
Just copy the PIN number and paste back in the terminal and hit enter.
You will get a message in the terminal Authorization successful.
Go to yor APP_Name page https://developer.twitter.com/en/apps/123456 and go to Keys and tokens section. You need to regenerate the Access token & access token secret. Hit the button 'regenerate'
Once it is regenerate you can get access to the api trough twurl in your terminal: $ twurl -H "ads-api.twitter.com" "/5/accounts". Please note that today (May-2019) I am using number 5 in "/5/accounts". You must to check your version at your date.
Now you can get access to the Twitter Ads API trough curl in php also.
Create a class TwitterAPIExchangeService (I am in Laravel 5.8). You can get the class in this post.
Use the follow code with your keys:
$settings = array(
'oauth_access_token' => env('TWITTER_ACCESS_TOKEN'),
'oauth_access_token_secret' => env('TWITTER_ACCESS_TOKEN_SECRET'),
'consumer_key' => env('TWITTER_CONSUMER_KEY'),
'consumer_secret' => env('TWITTER_CONSUMER_SECRET'),
);
//Regular Twitter API
$url = 'https://api.twitter.com/1.1/followers/ids.json';
$getfield = '?screen_name=J7mbo';
//Ads Twitter API
//$url = 'https://ads-api.twitter.com/5/accounts';
//$getfield = '';
$requestMethod = 'GET';
$twitter = new TwitterAPIExchangeService($settings);
$data = $twitter->setGetfield($getfield)
->buildOauth($url, $requestMethod)
->performRequest();
dd($data);
Need to regenerate keys and tokens. after that its work for me

Is PayPal permission required to use SetExpressCheckout for a third party?

We are processing payments on behalf of third parties using SetExpressCheckout. It appears to work correctly even though the third party has not granted us permissions. Are we doing it correctly?
From what I have understood, in order to process payment for a third party the third party should go to Tools > API credentials > Grant API Permission in their PayPal account and grant permission to our API username to Use Express Checkout to process payments. However, we have noticed two issues with this:
If the third-party PayPal account is just a personal account (not a business account) then there is no option to grant API permissions
Even if the non-business third-party PayPal account doesn't grant this permission we are still able to take payment into their account.
So the question is, is it actually necessary for a third party to grant us this permission in order for us to be able to process payments which are crediting their PayPal accounts?
In case you need more information, here is a cut-down version of the PHP code we are using to start the SetExpressCheckout request. We are specifying the third-party using the SUBJECT parameter of the request, this parameter is filled in with the email address of the third-party's PayPal account.
// Parameters for SetExpressCheckout
$requestParams = array(
'METHOD' => 'SetExpressCheckout',
'VERSION' => $this->_version,
'PAYMENTREQUEST_0_DESC' => "Order number",
'PAYMENTREQUEST_0_AMT' => 10,
'PAYMENTREQUEST_0_CURRENCYCODE' = 'EUR',
'PAYMENTREQUEST_0_ITEMAMT' => 10,
'RETURNURL' => "http://SUCCESS_URL_TO_RETURN_TO",
'CANCELURL' => "http://FAILURE_URL_TO_RETURN_TO",
'USER' => 'OUR_API_USERNAME',
'PWD' => 'OUR_API_PASSWORD',
'SIGNATURE' => 'OUR_API_SIGNATURE',
'SUBJECT' => 'THIRD_PARTY_EMAIL'
);
// Options for curl
$curlOptions = array (
CURLOPT_URL => 'https://api-3t.paypal.com/nvp',
CURLOPT_VERBOSE => 1,
CURLOPT_SSL_VERIFYPEER => true,
CURLOPT_SSL_VERIFYHOST => 2,
CURLOPT_CAINFO => 'cacert.pem', //CA cert file
CURLOPT_RETURNTRANSFER => 1,
CURLOPT_POST => 1,
CURLOPT_POSTFIELDS => http_build_query($requestParams)
);
// Send the curl request
$ch = curl_init();
curl_setopt_array($ch,$curlOptions);
$response = curl_exec($ch);
// Handle possible errors
if (curl_errno($ch)) {
//Handle errors
} else {
// Handle success
}
curl_close($ch);
If third-party accounts are not required to grant us permission then we can simplify setup of PayPal by simply asking for their PayPal account's email address, and not have to bother them with granting permissions.
Many thanks for any information you can give.
There are two ways to make API calls on behalf of others. 1) Grant API permissions from merchant PayPal account to API caller OR 2) Use SUBJECT NVP variable with the merchant PayPal account email address('SUBJECT' => 'THIRD_PARTY_EMAIL').
So you can make the API calls on behalf of the merchant just by using the SUBJECT NVP variable with merchant PayPal account email address, here the merchant no need to grant API permissions to you.

RESTful API using JWT (JSON Web Token) setup token expiry

I'm using JWT for RESTful API (Laravel Web-Services for mobile). How to setup token expiry to never expiry or what the best practice to setup token expiry?
Because currently i need to get the token everytime when the token expired, can anybody have this issue or best solution for token expiry.
There is nothing to make the token never expire. However you can extend the expiration date to a very huge time span, 1 year for example. This is possible, however it is not recommended for security.
In order to achieve that, you need to configure two parts, the token refresh time, and token expiry.
So in config/jwt.php
'refresh_ttl' => 29030400, // Number of minutes in 1 year (12*4*7*24*60*60)
And when you are creating your token, you can pass something like the following
$tokenId = base64_encode(mcrypt_create_iv(32, MCRYPT_DEV_URANDOM));
$issuedAt = Carbon::now()->timestamp;
$notBefore = $issuedAt; //Adding 10 seconds
$expire = $notBefore + 12*4*7*24*60*60; // Adding 6 hours
/*
* Create the token as an array
*/
$data = [
'iat' => $issuedAt, // Issued at: time when the token was generated
'jti' => $tokenId, // Json Token Id: an unique identifier for the token
'iss' => 'https://example.com', // Issuer
'nbf' => $notBefore, // Not before
'exp' => $expire, // Expire
'data' => [ // Data related to the signed user
'userId' => Auth::user()->id, // userid from the users table
]
];
Now, your token will never expire before 1 year. And you have up to 1 year to refresh it. When the user opens the application the next time, and you authenticate the token, you can refresh it. You can refresh the token, as mentioned in the documentation here. I would recommend going through this laracasts discussion as well.
Also, I have found this question on StackOverflow, I think it will help.

Laravel Auth attempt hashing

In a login form, I have this Auth check:
$auth = Auth::attempt([
'email' => Input::get('email'),
'password' => Input::get('password'),
'active' => 1
], $remember);
Now this Auth check is taking the raw input from the input field. Yet my database of which this is Authorising against stores the password in an encrypted state using Hash::make().
This login form works perfectly fine. The user logs in with the correct password, but it uses a raw password in the Auth function against a hashed password, yet returns true.
Why is this?
The Auth class does the hashing in the background and compares the password the same way you would normally.

How to post to a users wall from inside Rails model

My application gets approved and a user gets an access token and extended permissions which include offline_access and publish_stream.
I want to be able to post from inside my model. This would require me to make an
https://graph.facebook.com/FBUSER_ID/feed
plus some parameters and access token, app_id, app_secret.
I have the access token and FBUSER_ID.
What I don't know how to do is put it all together in the model.
Could anyone point me in the right direction?
I already have a facebook application. I need to know how to post from the server to a users wall
**Thanks to the answer below I was able to get it working with the following:
access_token = "AAACvmqy1nYoBAAZCkGXbVgRwcBv******ZAMjsLxKxR7DaZBE0NxY8ZBGBW1q2mzsB9TDT0RvgeQcDdnyFJNAYRf0icnhlbikZD"
appID = '1776938807888574888888888882'
message = 'test_message'
userID = '75164088804088888'
uri = URI.parse("https://graph.facebook.com/#{userID}/feed")
req = Net::HTTP::Post.new(uri.path)
result = req.set_form_data({:access_token => access_token , :message => message, :app_id => appID })
sock = Net::HTTP.new(uri.host, 443)
sock.use_ssl = true
sock.start do |http|
response = http.request(req)
end
IMPORTANT: at the top of the controller or model add:
require 'openssl'
First you have to create a Facebook application here. By the app_id and app_secret of created application, you will ask user to give "publishing feed" permission to your application. While getting this permissions you get also the access token for posting the users wall.
You can get detailed info about authentication here:
https://developers.facebook.com/docs/authentication/
And you can get info about publishing here on the Publishing section:
http://developers.facebook.com/docs/reference/api/
With ruby, your need is just making an HTTP Post. This may be an example for this:
Net::HTTP.post_form(URI.parse('https://graph.facebook.com/FBUSER_ID/feed'),
{'access_token' => 'ACCESS_TOKEN', 'message' => 'MESSAGE'})