I'm struggling to get user info after authenticating using the auth0 PHP SDK. This is on my localhost using ngrok. I'm just using the basic example files in the SDK and I'm able to log in fine. However, after login when it re-directs to my callback url and attempts to exchange the auth code, I get a 401 error with "unauthorized".
Here is the error in wamp:
In the logs I can see that the login happened successfully, but when attempting to exchange the auth code, it fails.
I can also confirm that I'm getting the code and the state back in my query parameters:
https://myurl.ngrok.io/auth/?code=ygKukP3B5_xk0pbb&state=5ae5b7a643aa46.52329844
I've made a couple of slight modifications to the example files while trying to get this to work, but I don't think that's the culprit. Just in case, here's the code:
require 'vendor/autoload.php';
//require 'dotenv-loader.php';
use Auth0\SDK\Auth0;
$domain = 'mydomain.auth0.com';
$client_id = 'MYCLIENT';
$client_secret = 'MYSECRET';
$redirect_uri = 'https://myurl.ngrok.io/auth/';
$auth0 = new Auth0([
'domain' => $domain,
'client_id' => $client_id,
'client_secret' => $client_secret,
'redirect_uri' => $redirect_uri,
'persist_id_token' => true,
'persist_refresh_token' => true,
'audience' => 'https://mydomain.auth0.com/userinfo',
'scope' => 'openid profile'
]);
if (isset($_REQUEST['logout'])) {
$auth0->logout();
session_destroy();
header("Location: /");
die();
}
if(isset($_REQUEST['code'])) {
$userInfo = $auth0->getUser();
var_dump($userInfo);
} else {
$auth0->login();
}
UPDATE:
I also noticed that when the page first loads I get the previously mentioned error. If I refresh the page, I get Fatal error: Uncaught Auth0\SDK\Exception\CoreException: Invalid state
I had this issue on an application that was available on two subdomains a and b but uses only b as an configured application domain. When user accesses a Auth0's nonce (aka state) was created only for a leading to a failing validation due to an empty session when Auth0 redirected back to the configured application url on b.
I solved this issue by setting php's cookie domain to b.. Concretely in my laravel app i set the envvar
SESSION_DOMAIN=b
Related
I am quite new to wordpress and OAuth. I have two sites. One hosted on the web,and the second one hosted on my local machine. I want to use OAuth in order to login to my local machine site if i am logged in to the other site.
What i managed to do:
I had installed WP OAuth Server on web hosted site and created new client;
On my local machine i wrote the following code using https://github.com/adoy/PHP-OAuth2;
require('vendor/autoload.php');
const CLIENT_ID = 'my client id';
const CLIENT_SECRET = 'my client secret';
const REDIRECT_URI = '';
const AUTHORIZATION_ENDPOINT = '';
const TOKEN_ENDPOINT = '';
$client = new OAuth2\Client(CLIENT_ID, CLIENT_SECRET);
if (!isset($_GET['code']))
{
$auth_url = $client->getAuthenticationUrl(AUTHORIZATION_ENDPOINT, REDIRECT_URI);
header('Location: ' . $auth_url);
die('Redirect');
}
else
{
$params = array('code' => $_GET['code'], 'redirect_uri' => REDIRECT_URI);
$response = $client->getAccessToken(TOKEN_ENDPOINT, 'authorization_code', $params);
$response = (object) $response;
$result = (object) $response->result;
//echo json_encode($result->access_token);
echo "<pre>";
print_r($response);
}
When i run this script i got the following response:
stdClass Object
(
[result] => Array
(
[access_token] => rhfnpz6ifgnjufoq0rby0utphtzpxhrmsytnjh5z
[expires_in] => 86400
[token_type] => Bearer
[scope] => basic
[refresh_token] => lgrklt5kwiv29ch3nmdhhieedjbudg8liv48l6c7
)
[code] => 200
[content_type] => application/json
)
How can i use this access token in order to login to my local hosted site? What i am missing? Thank you!
After you have a response with the access_token you can log the user in without having to accept and process the normal WP email+password flow. Do this by
session the access_token and refresh_token (for future calls to the API Resource endpoint, if any)
call wp_set_auth_cookie() to create a WP session for the user.
You'll want to include in your code a hook for the WP logout where you'll clear the tokens from the session.
OAuth2 Server
Your web-hosted WordPress website needs an OAuth2 server plugin. This is our premium product: https://lana.codes/product/lana-passport/
The OAuth2 server plugin provides the authentication server that is connected to the WordPress user system. It also provides the /authorize, /token and /resource endpoints, to which the client can connect and generate a token, and then use the token to access user data.
Basically, the Authorization Code grant type should be used for this purpose, because it also provides the WordPress login interface if you are not logged in and need to identify yourself. This is the most user-friendly and most popular grant type.
OAuth2 Client
And your local machine-hosted WordPress website needs an OAuth2 client. This is our free product: https://wordpress.org/plugins/lana-sso/
This creates a Single Sign On button for the WordPress login interface, which is connected to the configured OAuth2 server.
How does it work:
If the client went through the authentication process and received the access_token, it requests the user data from the OAuth server at the /resource endpoint.
If the user can be found on the client website based on the user data, the user is logged in using the wp_set_current_user() and wp_set_auth_cookie() functions. If the user is not found and registration is enabled, a new user is created using the wp_insert_user() function on the client website and logged in.
If you want to know more about the OAuth2 process, we have a case study that specifically discusses the single sign on solution for two WordPress websites: https://lana.codes/case-study/oauth2-server-and-client-wordpress-plugin/
We're building a web app in PHP. We've set up SSL certificate and right after that the FB login stopped working. When the script tries to get user ID, exception is thrown
An active access token must be used to query information about the current user.
I'm 100% positive the SSL is the problem because it works fine on my localhost and it also worked on the production before setting up the SSL.
We're using Facebook PHP SDK. Here is the first part (getting login url)
$facebook = new Facebook([
"appId" => "APP_ID",
"secret" => "SECRET"
]);
$permissions = ["email", "user_birthday", "publish_stream", "offline_access"];
$loginURL = $facebook->getLoginUrl([
"scope" => join(",", $permissions),
"redirect_uri" => "REDIRECT_URI"
]);
// redirect to $loginURL
And here's the callback
$facebook = new Facebook([
"appId" => "APP_ID",
"secret" => "SECRET"
]);
$userID = $facebook->getUser();
$token = $_GET['code'];
if(isset($userID) && isset($token)) {
// ... some cool stuff
} else {
// error, something happened
}
Thanx for help
EDIT: I was getting the error because I was trying to get details about user by the $userID. Problem was, the $userID is always 0 so no wonder I got error. Somehow I can't get user's ID on the website with SSL...
OK in the end I found the cause of my problems and it was realy stupid (like almost always, right?). When I was building the callback URL that is sent as an argument to the FB login page, I was getting the base url with a method from the framework I use. For some reason it gave me domain.com:443/ instead of domain.com/. After I fixed it, it suddenly works.
In mu case it was the WWW that was missing from the redirect URL. SSL cert was working only with it
What are the basic steps for setting up a pure server flow facebook SSO, the docs are as usual a little ambiguous?
I set up the flow with javascript popups only to later realise you are not allowed to customise the login buttons.. which when you stick them next google and twitter sso the signin box look terrible.
http://www.codecademy.com/ seem to direct to their own server which then forwards onto a URL like this:
https://www.facebook.com/dialog/oauth?response_type=code
&client_id=212500508799908&
redirect_uri=http%3A%2F%2Fwww.codecademy.com%2Fauth%2Ffacebook%2Fcallback&state=8aac5bc63c5afe8fbabe572021e7750579fefd898d7b4316&
scope=email%2Cpublish_actions
How is this URL being generated? In the facebook docs there is a function "getLoginUrl".. is this being called which generates the correct URL?
I tried directing the user directly from their browser to:
var href = 'https://www.facebook.com/dialog/oauth?' +
'client_id='+app_id+'&'+
'redirect_uri=http://www.mysite.net/authenticate_facebook.php&'+
'scope=email&';+
'state='+$('body').attr('unique');
But the at the facebook php then the following recieving code resulted in errors about the 'state' not matching... I am assuming that the state is not just a random value generate by my server and must be aquired from the facebook server?
require_once(WEBROOT_PRIVATE.'authenticate/facebook-php-sdk/src/facebook.php');
$config = array(
'appId' => 'xxx',
'secret' => 'xxx',
'fileUpload' => false,
'allowSignedRequest' => false
);
$facebook = new \Facebook($config);
$user_id = $facebook->getUser();
if($user_id)
{
try
{
$user_profile = $facebook->api('/me','GET');
}
catch(FacebookApiException $e)
{
error_log($e->getType(), 0);
error_log($e->getMessage(), 0);
}
}
SO, is this correct flow:
1 - Direct the user to my server facebook_auth.php
2 - facebook_auth.php generate the get url and forwards the user onto it
3 - The user, if required logs into facebook, allows my app
4 - my facebook_auth.php script then checks the tokens and talks server to server with facebook to verify the rest
5 - my website then logs the user in
I had a similar issue last week, and tracked it down to the state field being overwritten by multiple calls to getLoginUrl(). Each time you call getLoginUrl(), a new state token is generated in the SDK and stored in the $_SESSION (it's just a random value), so if you call it twice and the user uses the first link to log in, the second call will have reset the SDK's internal state token, and you will get this error in your logs.
The SDK looks for the same state token in the URL coming back after Facebook authorizes the user and redirects them back to your site, and if it doesn't match it will log this error (here's a link to the source).
I'm writing a facebook application in PHP with the facebook SDK.
The important parts in my code are:
$facebook = new Facebook(array(
'appId' => $ApplicationID,
'secret' => $ApplicationSecret,
'cookie' => true, // enable optional cookie support
));
$user = $facebook->getUser();
$post = $facebook->api('/' . $user . '/feed', 'post', array(
stuff
));
$_SESSION['finish'] = false;
$_SESSION['inside'] = 'yes';
$_SESSION['uid'] = $user;
$token = $facebook->getAccessToken();
echo 'Access token: ' .$token;
$_SESSION['friends'] = $facebook->api('/me/friends?access_token'.$token);
You can see I am echoing the access token.
At first, I haven't added the access_token into the query - I just added it for checking.
The problem is that the last like (with the /me/friends/) throws an exception:
OAuthException: An active access token must be used to query information about the current user.
Although I did a login, and the feed post did work (I checked at my wall, it's there). Then, my try catch block handles the exception by redirecting to the login link, this way:
catch(Exception $e) {
$login_url_params = array(
'scope' => 'stuff',
'fbconnect' => 1,
'redirect_uri' => $ApplicationURL
);
$login_url = $facebook->getLoginUrl($login_url_params);
//redirect to the login URL on facebook
echo ("EXCPETION! " . $e . "<script> top.location.href='" . $login_url . "'</script>");
exit();
}
The code writing the exception is obviously only for debugging purposes.
Well, the first time I run the application a similar code is executed by a if(!$user) condition. Then it asks for my permission and I give it. Then, again, it says the access token is invalid (but does post to my wall).
Please note that I've compared the access_tokens, and even after removing the application and doing it all again - it stayed the same.
This is very awkward behavior and I fail to understand it. May anyone please shred some light on this?
Edit: For some weird reason, the token doesn't change even after going to a different user. But the post on the wall is still made... (And the exception thrown when accessing the friends list)
For some weird reason, the token doesn't change even after going to a different user. But the post on the wall is still made... (And the exception thrown when accessing the friends list)
That sounds to me as if you don’t actually have a user currently logged in, so the SDK is just using your app access token, which is always the default token it will use before it receives another, more “specific” one.
What format does your access token have – does is look something like your_app_id|your_app_secret or your_app_id|some_random_characters? If it’s starting with your app id, it’s most definitively an app access token.
I'm having some strange issues building an iframe app for Facebook. The app seems to get stuck in an infinite loop on the Go To App page.
After the user authorizes the app in the Go To App page, and returns to the app, the /me api call throws the "Error validating access token" exception. I checked and there is a valid access token in the Signed Request (tested with the facebook access token debuggin tool). I tried setting that with the setAccessToken() method unsuccessfully.
The getUser() method successfully returns the user ID, but it still hangs on the /me api call.
This doesn't happen in every browser, i'm just seeing it in Chrome sometimes in a no clear pattern. I fixed it in IE using the P3P header. It works fine in Firefox.
I pretty much stuck and i'm out of hair to pull out so any ideas are welcome. Thanks a lot.
The full error message: "Error validating access token: You cannot access the app till you log in to www.facebook.com and follow the instructions given."
Some code below.
$this->_facebook = new Facebook(
array(
'appId' => $this->_config['appId'],
'secret' => $this->_config['secret'],
'cookie' => true,
'fileUpload' => true
)
);
$this->_signedRequest = $this->_facebook->getSignedRequest();
// Doing something with signed request, not FB related
$this->_userId = $this->_facebook->getUser();
if($this->_userId) {
try{
// At this line the "Error validating access token" error shows up
$this->_user = $this->_facebook->api('/me');
// Some more irrelevant code here
} catch (Exception $e){
$this->_facebook->destroySession();
$this->_facebookLogin(false);
}
} else {
$this->_facebook->destroySession();
$this->_facebookLogin(false);
}
// The _facebookLogin method
public function _facebookLogin($perms = 'email,user_birthday,publish_stream,video_upload'){
$data = array(
'fbconnect' => 0,
'redirect_uri' => 'aredirecturl.com'
);
if(!empty($perms)) {
$data['scope'] = $perms;
}
echo '<script type="text/javascript">window.top.location.href = "'.$this->_facebook->getLoginUrl($data).'";</script>';
exit;
}
Edit this part
// At this line the "Error validating access token" error shows up
$this->_user = $this->_facebook->api('/me');
to this
// At this line the "Error validating access token" error shows up
$this->_user = $this->facebook->api('/me','GET');
What about destroying your session by hand? Did you debug these parameters?
unset($_SESSION['fb_'.$YOUR_API_KEY.'_code']);
unset($_SESSION['fb_'.$YOUR_API_KEY.'_access_token']);
unset($_SESSION['fb_'.$YOUR_API_KEY.'_user_id']);
unset($_SESSION['fb_'.$YOUR_API_KEY.'_state']);
I am almost using the same code as you,but I'm not using fileUpload and cookie parameters.