I am using Firebase authentication in my Flutter app to manage the users (Facebook, Google, Email...). When the user log in my app, I send the Firebase token to my PHP server, where that token is verified with JWT.
The problem is that, although the token generated by the email login is correctly verified, the token generated by the Facebook or Google login fails with "SignatureInvalidException: Signature verification failed".
Facebook login code in the Flutter app:
FirebaseAuth auth = FirebaseAuth.instance;
final LoginResult result = await FacebookAuth.instance.login();
final FacebookAuthCredential facebookAuthCredential = FacebookAuthProvider.credential(result.accessToken.token);
UserCredential user = await auth.signInWithCredential(facebookAuthCredential);
String token = await auth.currentUser.getIdToken();
print(token.toString());
The information of the token is correctly validated in the https://jwt.io/ debugger, so the header and the payload are fine.
In the PHP server (Same code for both cases):
Validating the email&password token (OK):
stdClass Object ( [iss] => https://securetoken.google.com/project-123546 [aud] => project-123546 [auth_time] => 1603424825 [user_id] => S2gpfdsa156dsacdsfQ2z1 [sub] => S2gpfdsa156dsacdsfQ2z1 [iat] => 1603424825 [exp] => 1603428425 [email] => user#example.com [email_verified] => [firebase] => stdClass Object ( [identities] => stdClass Object ( [email] => Array ( [0] => user#example.com ) ) [sign_in_provider] => password ) )
Validating the Facebook token (KO):
Fatal error: Uncaught Firebase\JWT\SignatureInvalidException: Signature verification failed in server\vendor\firebase\php-jwt\src\JWT.php:122 Stack trace: #0 server\token.php(18): Firebase\JWT\JWT::decode('eygswbdsasdJSUzI...', '-----BEGIN CERT...', Array) #1 {main} thrown in server\vendor\firebase\php-jwt\src\JWT.php on line 122
PHP code:
$token = "...TOKEN-FROM-APP...";
$pkeys_raw = file_get_contents('https://www.googleapis.com/robot/v1/metadata/x509/securetoken#system.gserviceaccount.com');
$pkeys = json_decode($pkeys_raw, true);
$decoded = JWT::decode($token, $pkeys, ["RS256"]);
print_r($decoded);
The KeyID match with the key in https://www.googleapis.com/robot/v1/metadata/x509/securetoken#system.gserviceaccount.com, but I think that the app (or Firebase) is not signing correctly the token with the private key in the Facebook and Google login. However, I am using auth.currentUser.getIdToken() too in the email&password login, so there are not differences.
Any idea how to resolve this?
Investigating in the firebase library for Flutter I found the answer to this problem. I post it here just in case it was helpfull for someone.
The library is fine and the signature is correctly generated.
The reason is totally unrelated to the library - debugPrint() in Flutter/Dart on the Android platform does not have enough buffer to print out the entire token string.
So the problem is the print(token.toString());, if you send the token to the server it will be correctly decoded.
All the info about this issue:
https://github.com/FirebaseExtended/flutterfire/issues/2728
I think you can use log to get the whole token:
log(token);
Even though jwt token is invalid somehow from https://jwt.io, but I am still able to verify it from my backend which is Java using Firebase Admin SDK.
FirebaseAuth.getInstance(firebaseApp).verifyIdToken(token);
Also, you can print like this:
final idToken = await firebaseCredential.user!.getIdToken(true);
print(idToken.substring(0, 1000));
print(idToken.substring(1000));
Related
So I have a client in python and a backend in PHP. The python client is using pyjwt and the php server is using Firebase JWT.
When encoding and decoding tokens within php everything works fine. But when I encode tokens from python and decode them with php the Firebase library returns an error:
Firebase\JWT\SignatureInvalidException Object
(
[message:protected] => Signature verification failed
[string:Exception:private] =>
[code:protected] => 0
[file:protected] => /var/www/vendor/firebase/php-jwt/src/JWT.php
[line:protected] => 110
...
The encoding python code is the following
import jwt
...
payload = {'sub': self.client.id, 'exp': (datetime.now() + timedelta(days=1)).timestamp()}
context['token'] = jwt.encode(payload, os.environ['JWT_KEY'], algorithm='HS256')
and the PHP code is the following
$key = getenv("JWT_KEY");
return (array) \Firebase\JWT\JWT::decode($token, $key, array('HS256'));
OK, I found the problem. The issue was the secret KEY ussed by the different parties. The key had a problem when trying to be readed by PHP and thats why it was creating different tokens. The libraries are ok, they can communicate between each other without any problem.
I was developing a Shopify App. It was working fine till yesterday evening, but then I started getting the Bad Request [400] error, after the user allow access to the app for his shop.
Error is below
(https://SHOP-NAME.myshopify.com/admin/oauth/access_token) in /path/to/shopify/authentication/oauth.php on line 28
Array (
[method] => POST
[uri] => https://SHOP-NAME.myshopify.com/admin/oauth/access_token
[query] => Array ( )
[headers] => Array ( )
[payload] => Array (
[client_id] => {CLIENTID}
[client_secret] => {CLIENT_SECRET}
[code] => {CODE}
)
)
I'm doing a POST cURL Request with Content-Type:application/x-www-form-urlencode and all the request are validated to be coming from shopify.
If anyone want more information I can provide.
Thanks.
If this happening after the user authorizes the app, it could be an issue with the permanent token they have received. You could try grabbing the token that is generated and doing a POSTMAN request manually to query the API to verify the token works.
If it worked before and you didn't make any changes to the app, it could be a temporary API issue, even though I found that to be rare with my app.
The code parameter that is sent from Shopify can only be used a single time.
If you re-make the original request that sends the code parameter to your server, you should be able to make the call successfully.
I have a website that uses the Twitter API (verrsion 1.1) with PHP and Zend framework 1 for validating the user name that is entered into a text input by a user of the application.
I created the app on Twitter and generated the Consumer Key (API Key), Consumer Secret (Secret API), Access Token and Access Token Secret.
General permissions: Read, write, and direct messages
Tokens permissions: Read and write
My PHP code for the authentication with Twitter is:
$config = array(
'version' => '1.1',
'signatureMethod' => 'HMAC-SHA1',
'callbackUrl' => 'http://example/main/twitter',
'siteUrl' => 'https://api.twitter.com/oauth',
'requestTokenUrl'=> 'https://api.twitter.com/oauth/request_token',
'accessTokenUrl' => 'https://api.twitter.com/oauth/access_token',
'authorizeUrl' => 'https://api.twitter.com/oauth/authorize',
'consumerKey' => self::$_consumeKey,
'consumerSecret' => self::$_consumeSecret
);
$session = new Zend_Session_Namespace('OAUTH_TWITTER');
$consumer = new Zend_Oauth_Consumer( $config );
$token = $consumer->getRequestToken();
$session->request_token = serialize($token);
$consumer->redirect();
When this code is executed, in the line:
$token = $consumer->getRequestToken();
returns the following error:
Could not retrieve a valid Token response from Token URL:
error code="215" Bad Authentication data.
I do not know what I did because previously was working perfectly. I researched for 2 weeks and still can not find the solution. I tried to create the application again, regenerate keys and tokens and change the time zone of my server to UTC but has not been solved.
If you need more information about me, please let me know.
I appreciate any information you can give me. Regards.
PD: sorry by my bad english
I am using the [Google Analytics API PHP] by wanze. I was able to set up authentication (using web auth only) and everything and I stored the token in a session. On another page, I use this code to find all the accounts the user logged in with.
session_start();
include('GoogleAnalyticsAPI.class.php');
$ga = new GoogleAnalyticsAPI();
$ga->auth->setClientId('replaces'); // From the APIs console
$ga->auth->setClientSecret('replaces'); // From the APIs console
$ga->auth->setRedirectUri('replaced'); // Url to your app, must match one in the APIs console
// Get the Auth-Url
$url = $ga->auth->buildAuthUrl();
// Set the accessToken and Account-Id
$ga->setAccessToken($_SESSION['accessToken']);
$ga->setAccountId('ga:xxxxxxx');
// Load profiles
$profiles = $ga->getProfiles();
print_r($profiles);
$accounts = array();
foreach ($profiles['items'] as $item) {
$id = "ga:{$item['id']}";
$name = $item['name'];
$accounts[$id] = $name;
}
// Print out the Accounts with Id => Name. Save the Id (array-key) of the account you want to query data.
// See next chapter how to set the account-id.
print_r($accounts);
I this returned:
Array
(
[http_code] => 403
[error] => Array
(
[errors] => Array
(
[0] => Array
(
[domain] => usageLimits
[reason] => accessNotConfigured
[message] => Access Not Configured. The API is not enabled for your project, or there is a per-IP or per-Referer restriction configured on your API key and the request does not match these restrictions. Please use the Google Developers Console to update your configuration.
[extendedHelp] => https://console.developers.google.com
)
)
[code] => 403
[message] => Access Not Configured. The API is not enabled for your project, or there is a per-IP or per-Referer restriction configured on your API key and the request does not match these restrictions. Please use the Google Developers Console to update your configuration.
)
)
<br />
<b>Warning</b>: Invalid argument supplied for foreach() in <b>/home3/chalzzy/public_html/dashboard/dashboard.php</b> on line <b>21</b><br />
Array
(
)
I see in a lot of places that I need to remove or set all refers in a "Referrals" section in the console but I can't seem to fins that in the new or old console. If it is there and I can't find it, can you please give me a url or a screenshot?
Also, these are all the APIs I have installed for this project:
Thanks in advance,
Ben
Also, let me know if you need more details!
Hey (I'm sorry it was a very stupid question),
What you have to do is add to your APIs list "Analytics API" in the Developers Console.
I am trying to write a small webapp that pulls data from Yammer. I have to go through Yammer's OAuth bridge to access their data. I tried using the Oauth php library and do the 3 way handshake. But at the last step, I get an error stating I have an invalid OAuth Signature.
Here are the series of steps:
The first part involves getting the request Token URL and these are the query parameters that I pass.
[oauth_version] => 1.0
[oauth_nonce] => 4e495b6a5864f5a0a51fecbca9bf3c4b
[oauth_timestamp] => 1256105827
[oauth_consumer_key] => my_consumer_key
[oauth_signature_method] => HMAC-SHA1
[oauth_signature] => FML2eacPNH6HIGxJXnhwQUHPeOY=
Once this step is complete, I get the request Token as follows:
[oauth_token] => 6aMcbRK5wMqHgZQsdfsd
[oauth_token_secret] => ro8AJxZ67sUDoiOTk8sl4V3js0uyof1uPJVB14asdfs
[oauth_callback_confirmed] => true
I then try to authorize the given token and token secret by passing the parameters to the authorize url.It takes me to Yammer's authentication page where I have allow my app to talk to Yammer.
Yammer then gives me a 4 digit code that I have to put back into my application which then tries to acquire the permanent access token. I pass the following information to the access token URL:
[oauth_version] => 1.0
[oauth_nonce] => 52b22495ecd9eba277c1ce6b97b00fdc
[oauth_timestamp] => 1256106815
[oauth_consumer_key] => myconsumerkey
[callback_token] => 61A7
[oauth_token] => 6aMcbRK5wMqHgZQsdfsd
[oauth_token_secret] => ro8AJxZ67sUDoiOTk8sl4V3js0uyof1uPJVB14asdfs
[oauth_callback_confirmed] => true
[oauth_signature_method] => HMAC-SHA1
[oauth_signature] => V9YcMDq2rP7OiZTK1k5kb/otMzA=
Here I am supposed to receive the Oauth Permanent access token, but instead I get a Invalid Oauth signature. I dont know what I am doing wrong. I use the same signaures to sign the request. Should I sign the request using the new token and secret? I tried that as well but to no avail. I even tried implementing this in java using signpost library and got stuck at the exact same place. Help Help!!
The callback_token was something Yammer introduced in response to an OAuth security advisory earlier this year. When OAuth 1.0a was released, it was instead named oauth_verifier. However, it's not unlikely that Yammer still supports their workaround but rename it and try again to be sure.
Also, the below is information from the Yammer Development Network yesterday:
Tomorrow we will be releasing some
changes to the Yammer API to
facilitate user network switching on
API clients. Most of the change is in
the OAuth Access Tokens call which
allows you to generate pre-authorized
OAuth access tokens for a given user.
One token will be generated for each
network they are in and your clients
switch networks by sending an API
request signed with the appropriate
token for that network.
I'm assuming that Yammer OAuth libraries might need to be updated per this change. I haven't taken a look at it yet.
Edit: My python-yammer-oauth library still works despite Yammer having changed things on their side.
Edit2: Could you try using signature method PLAINTEXT instead of HMAC-SHA1? I've had problems with Yammer and HMAC-SHA1.
I tried by using PLAINTEXT.. but for this method its giving me the same "Invalid OAuth signature" error even for requesting the token.
So is it possible to generate the access token we use HMAC-SHA1 and for accessing the actual API method i.e. for posting the message.. we use PLAINTEXT?
just found the problem!
I had forgotten to add an ampersand ("&") at the end of CONSUMER_SECRET. Perhaps this is your issue as well?