Custom wordpress login with API Rest and angular - wordpress

is there a way to create a Custom login with the API Rest of Wordpress and angular.
Currently I'm using the WP REST API - OAuth 1.0a Server plugin but I can´t figure out how to do it
Or maybe its posible using the two methods (Basic Authentication and OAuth)?
I would appreciate any help

I have been wrestling with this the past couple weeks. It kind of depends on your use case.
First, don't use Basic Auth. It's insecure and for development only. Not worth the time to set up.
OAuth (I think) is for when you already have a repository of users somewhere, and those users want to give your app approval to access their info, create an account for them, etc. Think of a "Login with Faceook!" button or something, that's OAuth. Could be wrong but I don't think that's what you want.
What I landed on, and what I think you are asking for, was JWT or JSON Web Token Auth. This is best for me because I want users to be able to create new user accounts and login to them completely within the app.
First, install the JWT Authentication for WP-API plugin:
https://wordpress.org/plugins/jwt-authentication-for-wp-rest-api/
This will expose a new endpoint for JWT authentication in the REST API. You will ping that endpoint with user credentials, and get a token response. You then store that token somehow (I'm currently using localStorage) and append it to the request headers of every request that requires permissions. De facto you are logged in! See the plugin docs for details. The example code for attaching the request is in AngJS, not Ang2/4, but the concept is the same. Here's an example from a service that posts a comment.
postComment(comment): any {
let headers = new Headers({ 'Authorization': 'Bearer ' + JSON.parse(localStorage.getItem('currentUser')).token});
let options = new RequestOptions({ headers: headers });
return this.http
.post(this._wpBase + "comments", comment, options)
.subscribe((res: Response) => {
res.json();
});
}
There is probably a fancier, global way to do this but I am still figuring it all out. Hope this is helpful!

Paste Following code in your themes function.php file.
Make sure that WP-REST-API plugin Should be installed on wordpress site
add_action( 'rest_api_init', 'register_api_hooks' );
function register_api_hooks() {
register_rest_route(
'custom-plugin', '/login/',
array(
'methods' => 'GET',
'callback' => 'login',
)
);
}
function login($request){
$creds = array();
$creds['user_login'] = $request["username"];
$creds['user_password'] = $request["password"];
$creds['remember'] = true;
$user = wp_signon( $creds, false );
if ( is_wp_error($user) )
echo $user->get_error_message();
return $user;
}
add_action( 'after_setup_theme', 'custom_login' );
Then your API will be created as
http://www.url.com/wp-json/custom-plugin/login?username=xyz&password=xyz
Try it with Postman You will get 200 as a response and user info

Related

Auto-Login user into Wordpress site displayed in react-native <WebView> from Firebase

I have a react-native app running on expo with a login screen on my react-native application. When the user logs in, a JWT token is retrieved from Firebase and passed on to a which opens up a Wordpress Site. What I am trying to do is to automatically pass this JWT token to the and log them into the Wordpress site.
I tried several options, like installing the Firebase Authentication plugin by miniOrange, but I didn't know how to make this happen using the free version. I also tried using a custom script using the Code Snippets plugin and entering the below code. I had already installed php-jwt on my root folder in wordpress using compose.
require __DIR__ . '/vendor/autoload.php';
use \Firebase\JWT\JWT;
add_action('init', 'handle_jwt_token');
function handle_jwt_token() {
if (!empty($_GET['jwt_token'])) {
$jwt_token = sanitize_text_field($_GET['jwt_token']);
// Decode and verify the JWT token
$jwt_decoded = JWT::decode($jwt_token, YOUR_FIREBASE_PROJECT_ID, array('HS256'));
// Get the user data from the JWT token
$user_id = $jwt_decoded->sub;
$user_email = $jwt_decoded->email;
$user_name = $jwt_decoded->name;
// Log the user into Wordpress
$user = get_user_by('email', $user_email);
if (!$user) {
// Create a new Wordpress user if they don't already exist
$user_id = wp_create_user($user_email, wp_generate_password(), $user_email);
wp_update_user(array(
'ID' => $user_id,
'display_name' => $user_name,
));
}
wp_set_current_user($user->ID);
wp_set_auth_cookie($user->ID);
wp_redirect("https://homepage_url.com");
exit;
}
}
I just ended up getting an error
Uncaught Error: Failed opening required '/var/www/vhosts/test.com/html/wp-content/plugins/code-snippets/php/admin-menus/vendor/autoload.php' (include_path='.:') in /var/www/vhosts/test.com/html/wp-content/plugins/code-snippets/php/admin-menus/class-edit-menu.php(253)
My question is, are there any options available for me to achieve this? Thank you for your time in reading this!
You will able to achieve it with this extension.
https://firebase-wordpress-docs.readthedocs.io/en/latest/extensions/jwt.html#remote-authentication-via-url
It will require you generate a token on your React Native and pass it to the WebView, after that WordPress can handle the auto login.
You can try it here: https://dn-wp-autologin.web.app/

Google analytics 4 API with authentication

My website already has universal analytics and we are displaying different analytics profile data on our dashboard by authenticating users. Because each user will have access to a different analytics profile. So the steps we follow in UA are,
Ask the user to authenticate.
Get auth code and create an access token.
Passing access token to listManagementProfiles API to get the list of profiles for the authenticated user.
Based on the selected profile we display the analytics data. (we use google service analytics library)
sample code:
if (!class_exists('Google_Client')) {
require_once '/lib/google-api-php-client-master/src/Google/Client.php';
require_once '/lib/google-api-php-client-master/src/Google/Service/Analytics.php';
}
$this->client = new Google_Client();
$this->client->setApprovalPrompt('force');
$this->client->setAccessType('offline');
$this->client->setClientId('************');
$this->client->setClientSecret('*************');
$this->client->setRedirectUri('*****************');
$this->client->setScopes('https://www.googleapis.com/auth/analytics');
$this->client->setDeveloperKey('*************************');
$this->service = new Google_Service_Analytics($this->client);
$accessToken = $this->client->authenticate($authCode);
if ($accessToken) {
$this->client->setAccessToken($accessToken);
return true;
} else {
return false;
}
Where I'm stuck?
I've checked for the GA4 documentation and followed the steps provided in the doc. I have created the account/property for GA4 in one of my google accounts.
I then enabled the analytics service from google console.
Created service account.
Downloaded JSON file.
Downloaded the google admin client library from here
GA4 sample code:
require 'vendor/autoload.php';
use Google\Analytics\Admin\V1alpha\AnalyticsAdminServiceClient;
use Google\Analytics\Data\V1beta\BetaAnalyticsDataClient;
use Google\Analytics\Data\V1beta\DateRange;
use Google\Analytics\Data\V1beta\Dimension;
use Google\Analytics\Data\V1beta\Metric;
putenv('GOOGLE_APPLICATION_CREDENTIALS=config.json');
$client = new AnalyticsAdminServiceClient();
$accounts = $client->listAccountSummaries();
But this does not require the access_token and without an access token, it allows to fetch the accounts lists. I don't want the manual process of giving access to the service account for each analytics account.
I want my user to authenticate to my website and then only do the rest process based on it.
How can I achieve that?
I also read something that GA4 does not have profiles(views), then how can I access the profile data in GA4? do I need to list down the accounts/properties list to the user for selection?
I need the referral, organic search, users, and session data on my website. What endpoint of GA4 provides this data?
Any other library do I need to use?
I think you are close. You are just mixing oauth and service account.
With your UA analytics code you are using the Google analytics reporting api / google analytics management api to request access of the user to access their Google analytics accounts. You are currently using Oauth2 to request access of a user to access "their" google analytics accounts. These are accounts that they control.
With your GA4 accounts you are connecting to the google analytics admin api though you are currently using a service account.
Service accounts must be pre authorized. They are intended for use with accounts that the developer owns. You need to swtich it to use Oauth2 and not a service account. This way the users will be authenticated to their own account.
Google analytics admin Oauth2
Here is a sample with Oauth2.
<?php
// composer composer require google/analytics-admin
require 'vendor/autoload.php';
use Google\Client;
use Google\Analytics\Admin\V1alpha\AnalyticsAdminServiceClient;
putenv('GOOGLE_APPLICATION_CREDENTIALS=C:\YouTube\dev\credentials.json'); // Installed app credentials.
$credentials = getenv('GOOGLE_APPLICATION_CREDENTIALS');
$myfile = file_get_contents($credentials, "r") ;
$clientObj = json_decode($myfile);
$client = getClient();
$tokenResponse = $client->getAccessToken();
print_r($tokenResponse);
print_r($tokenResponse["access_token"]);
$service = new AnalyticsAdminServiceClient( [
'credentials' => Google\ApiCore\CredentialsWrapper::build( [
'scopes' => [
'https://www.googleapis.com/auth/analytics',
'openid',
'https://www.googleapis.com/auth/analytics.readonly',
],
'keyFile' => [
'type' => 'authorized_user',
'client_id' => $clientObj->installed->client_id,
'client_secret' => $clientObj->installed->client_secret,
'refresh_token' => $tokenResponse["refresh_token"]
],
] ),
] );
$accounts = $service->listAccounts();
foreach ($accounts as $account) {
print 'Found account: ' . $account->getName() . PHP_EOL;
}
function getClient()
{
$client = new Client();
$client->setApplicationName('Google analytics admin beta Oauth2');
$client->setScopes('https://www.googleapis.com/auth/analytics.readonly');
$client->setAuthConfig(getenv('GOOGLE_APPLICATION_CREDENTIALS'));
$client->setAccessType('offline');
// Load previously authorized token from a file, if it exists.
// The file token.json stores the user's access and refresh tokens, and is
// created automatically when the authorization flow completes for the first
// time.
$tokenPath = 'tokenAdmin.json';
if (file_exists($tokenPath)) {
$accessToken = json_decode(file_get_contents($tokenPath), true);
$client->setAccessToken($accessToken);
}
// If there is no previous token or it's expired.
if ($client->isAccessTokenExpired()) {
// Refresh the token if possible, else fetch a new one.
if ($client->getRefreshToken()) {
$client->fetchAccessTokenWithRefreshToken($client->getRefreshToken());
} else {
// Request authorization from the user.
$authUrl = $client->createAuthUrl();
printf("Open the following link in your browser:\n%s\n", $authUrl);
print 'Enter verification code: ';
$authCode = trim(fgets(STDIN));
// Exchange authorization code for an access token.
$accessToken = $client->fetchAccessTokenWithAuthCode($authCode);
$client->setAccessToken($accessToken);
// Check to see if there was an error.
if (array_key_exists('error', $accessToken)) {
throw new Exception(join(', ', $accessToken));
}
}
// Save the token to a file.
if (!file_exists(dirname($tokenPath))) {
mkdir(dirname($tokenPath), 0700, true);
}
file_put_contents($tokenPath, json_encode($client->getAccessToken()));
}
return $client;
}
Note this is a console app, not a web app. You may have to tweek it to work with web but you should just be able to copy your UA auth code and dump the tokens in as i have shown here.
Code shamelessly copied from Simple How to Integrate php with Google analytics admin api.
To fetch Account Summaries using Access Token, you can use Google APIs Client Library for PHP
Here is the working code
<?php
require_once 'vendor/autoload.php';
use Google\Client;
use Google\Service\GoogleAnalyticsAdmin;
$access_token = 'ya29.xxxxxxx';
// Init Google Client and Set Access Token
$client = new Client();
$client->setAccessToken($access_token);
// GA Admin Service
$service = new GoogleAnalyticsAdmin($client);
// Fetch Account Summaries
$summary = $service->accountSummaries->listAccountSummaries();
// Output
print_r($summary->toSimpleObject());
Output
stdClass Object
(
[accountSummaries] => Array
(
[0] => stdClass Object
(
[account] => accounts/XXXXXXX
[displayName] => XXXXXXX
[name] => accountSummaries/XXXXXXX
[propertySummaries] => Array
(
[0] => stdClass Object
(
[displayName] => XXXXXXX GA4 Property
[parent] => accounts/XXXXXXX
[property] => properties/XXXXXXX
[propertyType] => PROPERTY_TYPE_ORDINARY
)
)
)
[1] => stdClass Object
(
[account] => accounts/XXXXXX
[displayName] => XXXXXXX accounts
[name] => accountSummaries/XXXXXX
)
)
)

Wordpress get user info from same browser logged into site

I'm trying to use the Wordpress API wp_get_current_user(), however it's always returning the 0 user, with empty data. I am on a fresh install of Wordpress and I have just created my own theme and added an API hook.
I see lots of guides/info on grabbing data using Nonce from a separate client/computer, but I'm just trying to get the $user from the same browser that should be already logged in via the wordpress admin interface. I've verified that my browser has cookies set. My understanding of verification is that wp_get_current_user() should be able to use these cookies to verify my user and return data. .
Just to show I am logged into wordpress
This is my functions.php
located under wp-content/themes/myapi/functions/
add_action('rest_api_init', function () {
register_rest_route( 'api', 'test',array(
'methods' => 'GET',
'callback' => 'logged_in_wp',
));
});
function logged_in_wp($request){
if ( is_user_logged_in() ) {
return new WP_Error( 'me', 'me', array( 'status' => 200 ) );
}
return new WP_Error( 'not-logged in WP', 'not-logged in WP', array( 'status' => 400 ) );
}
?>
I'm using the following URL to access the data
http://localhost:8080/?rest_route=/api/test
I'm expecting it to return a me,me,200, instead, i'm only seeing the not-logged-in 400 error.
so what is the difference between localhost:8080 and localhost:8080?rest_route=/api/test that wordpress cannot figure out that I am logged in?
So, I'm guessing since nobody is answering and based on the readings I've done. What I'm asking for is impossible. It seems it is a security response by wordpress. You will need to authenticate even if the user is logged into Wordpress on the same domain/browser.
What do you use to test your request?
Using postman, you can insert useful parameters which will help you on authentication. Hence if you want to logged in using the WordPress Rest api, you must insert information of the current user properly in the section Authorization (Chose basic authentication and inside, fill the username and the password of an existing account (in this case Admin) and try it again.
Here is what i did for an exemple:
Sample image for the authorization which will soon help to know about the current user login
next using
$user_id = username_exists($username);
$user = get_user_meta($user_id);
$response['code'] = 200;
using "get_user_meta(wp_get_current_user()->ID, 'nickname', true);"
you can now determine the current user been logged.
Here in this sample if you make good use of the above information, you can create a good function "logged_in_wp()".
Here is my result on postman
I hope this will help you by the way

Cannot Authenticate Salesforce in a Wordpress Plugin

I'm getting an error (INVALID_SESSION_ID) when trying to send an authenticated GET request to Salesforce.com.
Here is the plug-in in its entirety, which basically just outputs the body of the REST response to whatever page has the [MembershipTables] shortcode:
if (!class_exists('WP_Http')) {
include_once(ABSPATH . WPINC . '/class-http.php');
}
// This is obviously the real username
$username = 'xxxx#xxxx.xxx';
// And this is obviously the real password concatonated with the security token
$password = 'xxxxxxxxxxxxxx';
function getMembershipTables() {
$api_url = 'https://na15.salesforce.com/services/apexrest/directory';
$headers = array('Authorization' => 'Basic ' . base64_encode("$username:$password"));
$args = array('headers' => $headers);
$request = new WP_Http;
$result = $request->request($api_url, $args);
$body = $result['body'];
echo "$body";
}
add_shortcode( 'MembershipTables', 'getMembershipTables' );
I should note that I can successfully hit this endpoint with Curl, though I use a session token I get from Salesforce using the old SOAP API to keep it equivalent (i.e., no client id/secret).
Am I doing something wrong with WP_Http? Or cannot I not authenticate a salesforce.com request using basic auth?
Thanks.
The salesforce API does not support Basic authentication, you need to call it with a sessionId. You can obtain a sessionId by various methods include interactive & programatic OAuth2 flows, and via a Soap login call.
Basis Interactive had a similar problem to solve. When I worked on the project I opted to to call the SalesForce CRM via the preset form plugin and a custom JS Cookie PHP Wordpress Plugin. We had this problem easily resolved by developing custom calls to SalesForce CRM via a getRequest in PHP passing data to the SalesForce CRM.
Test Site in Use:
http://newtest.medullan.com/wp/?page_id=3089
Here is the code and recycle the logical queries
Download Link:
http://basisinteractive.net/webdesign.html#wordpress

PHP SDK: How do I capture the access token after user auths app?

This is for a canvas app on the Facebook Platform using the new(est) Facebook PHP SDK.
We are using the PHP example from the Facebook tutorial (https://developers.facebook.com/docs/appsonfacebook/tutorial/) to trigger the OAuth dialog and get the test user to the redirect URL.
At the redirect URL, we use the PHP example from the Facebook signed request docs page (https://developers.facebook.com/docs/authentication/signed_request/) and our test users can successfully authorize the app.
However, after the test user auths the app, we are not able to capture the access token and its expiration. We can see it in the address bar appended to the redirect URL, but it does not show up in the $_REQUEST array. If we add {$access_token = $facebook->getAccessToken();} to the redirect URL page, it shows a value for the access token, but the value it shows is not the full token string that we see when we click on Show Token in the Test User Roles page (which we believe is the correct access token for the test user).
Here is an example of the redirect URL with an access token appended:
http://karmakorn.com/karmakorn/alpha20/kk-fb-auth.php#access_token=126736467765%7C2.AQDavId8oL80P5t9.3600.1315522800.1-100002908746828%7CJICJwM1P_97tKmqkEO5pXDCf-7Y&expires_in=6008
Here is what var_dump shows for the $REQUEST array for that same page:
array(3) { ["_qca"]=> string(26) "P0-709927483-1291994912966" ["__switchTo5x"]=> string(2) "30" ["PHPSESSID"]=> string(26) "euois02ead39ijumca7nffblh2" }
We have no idea why the $_REQUEST array varies from the values appended to the URL, and more importantly -- how to capture the access token and its expiration date.
Can someone show us a working example of how they capture this data after running the parse_signed_request($signed_request, $secret) function on the redirect page? Thanks!
ADDITIONAL INFO:
Here is the pertinent code from A) our test index page, and B) our test redirect page. If we use our text index page as the redirect url it gets stuck in an endless loop -- because the user is never identified.
A) Index Page
// Create kk-fb app instance
$facebook = new Facebook(array(
'appId' => KKFB_ID,
'secret' => KKFB_KY,
'oauth' => true,
));
$app_id = KKFB_ID;
$secret = KKFB_KY;
$canvas_auth = 'http://karmakorn.com/karmakorn/alpha20/kk-fb-auth.php';
$auth_url = "https://www.facebook.com/dialog/oauth?"
. "client_id=" . $app_id
. "&redirect_uri=" . urlencode($canvas_auth)
. "&response_type=token"
. "&scope=email,publish_stream";
$signed_request = $_REQUEST["signed_request"];
list($encoded_sig, $payload) = explode('.', $signed_request, 2);
$data = json_decode(base64_decode(strtr($payload, '-_', '+/')), true);
if (empty($data["user_id"])) {
echo("<script> top.location.href='" . $auth_url . "'</script>");
} else {
echo ("Welcome User: " . $data["user_id"]);
}
B) Redirect Page
// Create kk-fb app instance
$facebook = new Facebook(array(
'appId' => KKFB_ID,
'secret' => KKFB_KY,
'oauth' => true,
));
$app_id = KKFB_ID;
$secret = KKFB_KY;
$signed_request = $_REQUEST["signed_request"];
list($encoded_sig, $payload) = explode('.', $signed_request, 2);
$data = json_decode(base64_decode(strtr($payload, '-_', '+/')), true);
$user = $facebook->getUser();
$access_token = $facebook->getAccessToken();
echo "User: $user <br>";
echo "Access Token: $access_token <br>";
echo "Signed Request: $signed_request <br>";
var_dump($_REQUEST);
Here is what shows up as these echo results:
User: 0
Access Token: 126736467765|**SECRET**
Signed Request:
array(3) { ["_qca"]=> string(26) "P0-709927483-1291994912966" ["_switchTo5x"]=> string(2) "30" ["PHPSESSID"]=> string(26) "frugi545cdl15gjind1fnv6pq1" }
Interestingly, when the test user goes back to the index page the if condition is satisfied and we can get the correct access token:
Welcome User: 100002908746828
Access Token: 126736467765|2.AQBgcyzfu75IMCjw.3600.1315544400.1-100002908746828|m5IYEm976tJAkbTLdxHAhhgKmz8
Obviously, we are still missing something!? Also, we need to learn how to get the expiration time as a variable too so we can store both of these in our database.
OK, let's try this again.
Server-side vs Client-side Authentication
You are exclusively using the PHP SDK, so you want to do server-side authentication, where the authentication code is sent to the server over HTTP via the URL. This will allow you to fetch an access token for the user on the first page load after auth (in your case, the redirect page). The auth_url you are currently constructing is setting response_type=token, which forces the redirect to use client-side auth mode and set the token in the URL fragment instead of in the query. You should remove that parameter completely. In fact, I highly recommend you just use the PHP SDK instead of constructing that URL yourself. See example below.
Application Access Tokens
The odd-looking access token 126736467765|SECRET is your application access token, which is composed of your app ID and secret key. The application access token is returned by getAccessToken() if no user access token is available (because some API calls require at least some sort of access token). This also means that you've revealed your secret key to the world via this blog post, so you should reset your app secret otherwise anyone will be able to make API calls on your behalf. I highly recommend you elide parts of your access tokens if you share them with others.
Token Expiration
The OAuth 2.0 flow and v3.1.1 of the PHP SDK don't make determining the expiration time of a token all that easy. I would suggest attempting to make the API call, and then refreshing the token if the API call fails with an OAuthException. Tokens can be invalid even if they haven't expired, so this deals with more cases. However, if you still want to maintain the expiration date on your end, you might just want to extract it from the token itself. If you have an expiring token, then the expiration timestamp will be contained within that string. Here's a function I put together quickly to extract that:
function extractExpirationFromToken($access_token) {
$segments = explode('|', $access_token);
if(count($segments) < 2) { return 0; }
$segments = explode('.', $segments[1]);
if(count($segments) < 4) { return 0; }
$expires = $segments[3];
$dash_pos = strrpos($expires, '-');
if($dash_pos !== false) {
$expires = substr($expires, 0, $dash_pos);
}
return $expires;
}
New Index Page Code
// Create kk-fb app instance
$facebook = new Facebook(array(
'appId' => KKFB_ID,
'secret' => KKFB_KY,
));
$canvas_auth = 'http://karmakorn.com/karmakorn/alpha20/kk-fb-auth.php';
$auth_url = $facebook->getLoginUrl(array(
'scope' => 'email,publish_stream',
'redirect_uri' => $canvas_auth, // you could just redirect back to this index page though
));
$user = $facebook->getUser();
if (empty($user)) {
echo("<script> top.location.href='" . $auth_url . "'</script>");
} else {
echo ("Welcome User: " . $user);
}
Redirect Page
I don't think you need this page at all. You could just redirect the user back to your original index page.
// Create kk-fb app instance
$facebook = new Facebook(array(
'appId' => KKFB_ID,
'secret' => KKFB_KY,
));
$user = $facebook->getUser();
$access_token = $facebook->getAccessToken();
// also copy the function definition given earlier
$expiration = extractExpirationFromToken($access_token);
echo "User: $user <br>";
echo "Access Token: $access_token <br>";
echo "Expiration: $expiration <br>";
echo "Request: <br>";
var_dump($_REQUEST);
You can use the facebook build in method getAccessToken() for example;
$access_token = $facebook->getAccessToken();
This will give you the access token to your variable, now if you are getting it empty, remember to first check if the fuid is being properly catch, if it isn't you might need to review your settings be sure your "App Domain" is set this part is very important after setting it correctly you need to reset your app secret, then set your new values in your auth code. Hope this help, let me know :)
pd. Also remember to keep the scope of your variables visible in your whole php file or class.
Problem
The access_token in your pasted URL is not part of the query string, but instead contained in the URL fragment (after the #). URL fragments are not sent to the web server, and are readable only by client-side code like Javascript. Therefore the PHP SDK only sees http://karmakorn.com/karmakorn/alpha20/kk-fb-auth.php, which is why $_REQUEST does not contain an access_token key.
Questions / Notes
What are you using for your redirect_uri? I think you want to be using something like http://apps.facebook.com/your_canvas_url/
You shouldn't need to call parse_signed_request yourself or copy any code from the signed request page. The PHP SDK will do that for you. Just call:
$facebook = new Facebook(array(
'appId' => '…',
'secret' => '…',
));
$access_token = $facebook->getAccessToken();
Possible solutions
Also use the Facebook Javascript SDK. You can start by adding its <script> tag in your destination page (kk-fb-auth.php) (see the docs for full details; don't forget to set oauth: true). The JS SDK should set a cookie (named fbsr_126736467765) which the PHP SDK will be able to read via $_REQUEST or $_COOKIE on subsequent page loads.
If you want to do this with PHP, you can get the user's access token with a separate call to the Graph API at your redirect_uri. For this you need to change the response_type of your $auth_url in your index page to "code" or "code token".
Then, at your redirect page, Facebook will add a "code" parameter in the querystring. This API call will return you the full access_token and expiration time:
https://graph.facebook.com/oauth/access_token?
client_id=YOUR_APP_ID&
redirect_uri=YOUR_URL&
client_secret=YOUR_APP_SECRET&
code=$_REQUEST['code']
For more information you can refer to the docs on authentication.

Resources