Google Analytics OAuth2: How to solve error: "redirect_uri_mismatch"? - redirect

I'm trying to get this example to work: https://developers.google.com/analytics/devguides/config/mgmt/v3/quickstart/web-php#enable
The error I'm getting is "Error: redirect_uri_mismatch" .
In order to install the google api resources, I used composer with this command:
php composer.phar require google/apiclient:^2.0.0#RC
This installed the "vendor" folder in my root site folder. My index.php and oauth2callback.php files are located in the "public_html" folder.
Here's a screenshot of my error when going to my site:
The weird thing is that if I navigate to the link above that's included in the error message "Visit ...... to update the authorized..", I get this error message: " The OAuth Client Does Not Exist "
If I click on my only available Client ID, I can navigate to see the URI's which I'll screenshot below as well:
As you can see, under Authorized Javascript origins, I have http://localhost listed, and under authorized redirect URIs, I have my live site followed by the "oauthc2callback.php" file extension.
I don't understand how to get rid of the error I'm getting. I've tried replacing the URI's and putting in different JavaScript origins.
Also, for some reason on that last screenshot, it says that I don't have permission to edit this OAuth client, but I can make edits.
The code I have for index.php:
<?php
// Load the Google API PHP Client Library.
require_once '../vendor/autoload.php';
// Start a session to persist credentials.
session_start();
// Create the client object and set the authorization configuration
// from the client_secretes.json you downloaded from the developer console.
$client = new Google_Client();
$client->setAuthConfigFile('../config/client_secrets.json');
$client->addScope('https://www.googleapis.com/auth/analytics.readonly');
// If the user has already authorized this app then get an access token
// else redirect to ask the user to authorize access to Google Analytics.
if (isset($_SESSION['access_token']) && $_SESSION['access_token']) {
// Set the access token on the client.
$client->setAccessToken($_SESSION['access_token']);
// Create an authorized analytics service object.
$analytics = new Google_Service_Analytics($client);
// Get the first view (profile) id for the authorized user.
$profile = getFirstProfileId($analytics);
// Get the results from the Core Reporting API and print the results.
$results = getResults($analytics, $profile);
printResults($results);
} else {
$redirect_uri = 'http://' . $_SERVER['HTTP_HOST'] . '/oauth2callback.php';
header('Location: ' . filter_var($redirect_uri, FILTER_SANITIZE_URL));
}
function getFirstprofileId(&$analytics) {
// Get the user's first view (profile) ID.
// Get the list of accounts for the authorized user.
$accounts = $analytics->management_accounts->listManagementAccounts();
if (count($accounts->getItems()) > 0) {
$items = $accounts->getItems();
$firstAccountId = $items[0]->getId();
// Get the list of properties for the authorized user.
$properties = $analytics->management_webproperties
->listManagementWebproperties($firstAccountId);
if (count($properties->getItems()) > 0) {
$items = $properties->getItems();
$firstPropertyId = $items[0]->getId();
// Get the list of views (profiles) for the authorized user.
$profiles = $analytics->management_profiles
->listManagementProfiles($firstAccountId, $firstPropertyId);
if (count($profiles->getItems()) > 0) {
$items = $profiles->getItems();
// Return the first view (profile) ID.
return $items[0]->getId();
} else {
throw new Exception('No views (profiles) found for this user.');
}
} else {
throw new Exception('No properties found for this user.');
}
} else {
throw new Exception('No accounts found for this user.');
}
}
function getResults(&$analytics, $profileId) {
// Calls the Core Reporting API and queries for the number of sessions
// for the last seven days.
return $analytics->data_ga->get(
'ga:' . $profileId,
'7daysAgo',
'today',
'ga:sessions');
}
function printResults(&$results) {
// Parses the response from the Core Reporting API and prints
// the profile name and total sessions.
if (count($results->getRows()) > 0) {
// Get the profile name.
$profileName = $results->getProfileInfo()->getProfileName();
// Get the entry for the first entry in the first row.
$rows = $results->getRows();
$sessions = $rows[0][0];
// Print the results.
print "<p>First view (profile) found: $profileName</p>";
print "<p>Total sessions: $sessions</p>";
} else {
print "<p>No results found.</p>";
}
}
The code I have for "oauth2callback.php":
<?php
require_once '../vendor/autoload.php';
// Start a session to persist credentials.
session_start();
// Create the client object and set the authorization configuration
// from the client_secrets.json you downloaded from the Developers Console.
$client = new Google_Client();
$client->setAuthConfigFile('../config/client_secrets.json');
$client->setRedirectUri('http://' . $_SERVER['HTTP_HOST'] . '/oauth2callback.php');
$client->addScope('https://www.googleapis.com/auth/analytics.readonly');
// Handle authorization flow from the server.
if (! isset($_GET['code'])) {
$auth_url = $client->createAuthUrl();
header('Location: ' . filter_var($auth_url, FILTER_SANITIZE_URL));
} else {
$client->authenticate($_GET['code']);
$_SESSION['access_token'] = $client->getAccessToken();
$redirect_uri = 'http://' . $_SERVER['HTTP_HOST'] . '/';
header('Location: ' . filter_var($redirect_uri, FILTER_SANITIZE_URL));
}
All of this code was taken from the first website example, except with a few minor additions to make it match my system.
Anyone know how I can get rid of this error? What am I doing wrong?

Remember, as far as Google is concerned, "your" server is hostile until you name it "friendly", you must explicitly whitelist every possible source of an OAuth call TO Google.
Google is a clubbouncer, a big, ugly, unmovable bouncer with a a guest list saying to your application: "I will only deal with your request if your exact name OR id is on the list"
Have you tried including, not only localhost, but all other possible origins?
You must list every possible variation of url "root", including explicit IPs.
http://www.example.com
http://example.com
https://example.com
https://www.example.com
http://222.111.0.111
...
dont forget to include
https://accounts.google.com:443

The redirect Uri in the request MUST be exactly the same as one Uri you stored.
I see a / at the end of the stored one you missed in your request.

just copy the request URI on which error is occurring from error screen and paste it to OAuth credentials "Authorised redirect URIs"
now run the app.
this works for me. Hope I answered your query.

Related

Cannot login through Facebook in Laravel 5.1

I am trying to login with facebook using Laravel 5.1.
I am following each steps mention in laravel documentation.
http://laravel.com/docs/5.1/authentication#social-authentication.
But, When i login through facebook then it will redirect to my normal login page.
In sort Session is store in facebook login.
This is a Code that is written by me.
Router.php
Route::get('auth/facebook','Auth\AuthController#redirectToProvider');
Route::get('auth/facebook/callback','Auth\AuthController#handleProviderCallback');
AuthController.php
public function redirectToProvider()
{
return Socialite::driver('facebook')
->scopes(['email', 'public_profile'])
->redirect();
}
public function handleProviderCallback()
{
$user = Socialite::driver('github')->user();
$user = Socialite::driver('github')->user();
// OAuth Two Providers
$token = $user->token;
// OAuth One Providers
$token = $user->token;
$tokenSecret = $user->tokenSecret;
// All Providers
$user->getId();
$user->getNickname();
$user->getName();
$user->getEmail();
$user->getAvatar();
}
Services.php
'facebook' => [
'client_id' => '1625567400000000',
'client_secret' => 'secret',
'redirect' => 'http://localhost:8000/',
],
When i type localhost/8000/auth/facebook it will redirect me to facebook and ask permission for public_profile, email etc.
And it will redirect back to localhost/auth/login.
And when i type localhost:8000/auth/facebook/callback in URL, it will through error like this;
ClientException in Middleware.php line 69:
Client error: 404
For your case, I guest you are using middleware to check if the user is already logged in. And this might the problem that you get redirect to localhost/auth/login
I hope following code could be useful to you
public function handleProviderCallback()
{
//retrieve user's information from facebook
$socUser = Socialite::driver('facebook')->user();
//check user already exists in db
$user = \App\User::where('email', $socUser->getEmail())->first();
if($user) {
// if exist, log user into your application
// and redirect to any path you want
\Auth::login($user);
return redirect()->route('user.index');
}
//if not exist, create new user,
// log user into your application
// and resirect to any path you want
$user = new \App\User ;
$user->email = $socUser->getEmail();
// ...
// ...
// ...
$user->save();
\Auth::login($user); // login user
return redirect()->route('user.index'); // redirect
}
note: I did not test my code but you should get some idea
for more information: http://laravel.com/docs/5.1/authentication
and as #mimo mention,
Your redirect url in the Services.php file has to be
localhost:8000/auth/facebook/callback
Your redirect url in the Services.php file has to be
localhost:8000/auth/facebook/callback

Yii REST POST is not working in POSTMAN but in Framework

how could i post the form to the rest api action. Or how can i test the rest api for creating a record in the db with all the field values. Should we add create aq queryStringUrl. if its comming from a POST form action its fine. But this yii rest api should also work when called on a android device. I have used $_Request on post of the form , will the same work else where. if i wanna test the same in POSTMAN how can i do it. http://localhost/basic/web/site/create?fname=deepika&uname=deeps&email=deep#gmail.com&pwd=deepika&pwd_confirm=deepika&gender=female says 404 in postman. But works in the yii controller url This is the action i have created.
public function actionCreate()
{
$params=$_REQUEST;
//echo $params;
$model= new UsersForm();
if(isset($params['fname']))
$fname=$params['fname'];
if(isset($params['uname']))
$uname=$params['uname'];
if(isset($params['email']))
$email=$params['email'];
if(isset($params['pwd']))
$pwd=$params['pwd'];
if(isset($params['gender']))
$gender=$params['gender'];
if($fname == "" || $uname == "" || $email == "" || $pwd == "" || $gender == ""){
$this->setHeader(400);
echo "<pre>".json_encode(array('status'=>0,'error_code'=>400,'errors'=>"Something went wrong"),JSON_PRETTY_PRINT)."</pre>";
}else{
$model->fname = $fname;
$model->uname = $uname;
$model->email = $email;
$model->pwd = $pwd;
$model->pwd_confirm = $pwd;
$model->gender = $gender;
if($model->save()){
if($model->status == 0){
$mailSent = Yii::$app->mailer->compose()
->setFrom("noreply#gmail.com")
->setTo($model->email)
->setSubject("Proceed by Verification")
->setTextBody('Plain text content')
->setHtmlBody('<b>HTML content</b>')
->send();
// VarDumper::dump($mailSent, 10, true);die();
}
$this->setHeader(200);
echo "<pre>".json_encode(array('status'=>1,'success_code' => 200,'verification_mail'=>$mailSent,'message'=>'Registered Successfully'),JSON_PRETTY_PRINT)."</pre>";
}else{
$this->setHeader(400);
echo "<pre>".json_encode(array('status'=>0,'error_code'=>400,'errors'=>$model->errors),JSON_PRETTY_PRINT)."</pre>";
}
}
// VarDumper::dump($params, 10, true);die();
}
Without code examples its hard to say what goes wrong in your app. I think first of all if you creat new item by GET method, its not REST. In REST API cretion of new item goes by POST method (I say nothing about URL appearance). When I was realized REST in some project, I create simple methods at the backend application and then on frontend (JavaScript app) create simple method for send request to API URLs, and when I preparing headers to send, and then depending of url I set method to headers GET, POST, or PUT (no DELETE because we not deletin items throgh API). So it may be little bit confusing... But I believe when you will get things about REST you will resolve your problem.

Facebook API 2.2 - me/accounts - returns array(0)

I'm actually having troubles with the graph API :
https://developers.facebook.com/tools/explorer?method=GET&path=me%2Faccounts&version=v2.2&
I've been generating an access token with the extended permission 'manage_pages' and i'm trying a request on the edge 'me/accounts'.
The result is always :
{
"data": [
]
}
But I wished to get a page access token instead.
Is this a normal behavior, or did I miss something?
I also tried with the php SDK 4.0 with a short-lived and a long-lived token and got the same result...
My code is here:
$app_id = '-hidden-'; //Facebook App ID
$app_secret = '-hidden-'; //Facebook App Secret
$long_lived_token = '-hidden-'; // tested at https://developers.facebook.com/tools/debug/
//and giving - Expires :1429438313 (in about 2 months)
FacebookSession::setDefaultApplication($app_id , $app_secret);
$session = new FacebookSession($long_lived_token);
if ($session) {
try {
$user_permissions = (new FacebookRequest($session, 'GET', '/me/permissions'))
->execute()->getGraphObject(GraphUser::className())->asArray();
$found_permission = false;
foreach($user_permissions as $key => $val){
if($val->permission == 'manage_pages'){
$found_permission = true;
}
}
// if we got manage_pages
if($found_permission){
$user_token = (new FacebookRequest($session, 'GET', '/me/accounts'))
->execute()->getGraphObject(GraphUser::className())->asArray();
var_dump($user_token); //array(0) { } - Why?? Is this normal??
} else {
echo "Manage pages not granted!";
}
} catch(FacebookRequestException $e) {
echo "Exception occured, code: " . $e->getCode();
echo " with message: " . $e->getMessage();
}
}
Thanks for your help!
My user didn't have any pages to admin, this is why the array is empty.
I guessed page access token could be use to manage profile but I was wrong.
For anyone who had this problem and still couldn't solve, my problem is that I had generated a access_token before I was granted the admin privilege in the page I was looking for and because of that, I don't know why, I couldn't retrieve the page. I then deleted the access from my facebook page and when I generate a new token, it worked.

How to intercept and redirect each request on owncloud

I' struggling with a simple problem on owncloud 7.0
I'm creation an app that have to check a condition and redirect to a page to validate something. My target is to disable service usage until a condition is ok.
In the nominal scenario, user log in, system redirect user to the validation page if condition is not verified. So I use postLogin hook.
But if user try to change page without validating, I have to catch him and redirect it back to the validation page.
I have tried Middleware (owncloud interceptor), but they are not global, so second scenario fails.
Now I'm working with app loading and do something like
$app = new MyApp();
$c = $app->getContainer();
if ( $c->isLoggedIn() ) {
$requestedPath = path($_SERVER['REQUEST_URI']);
$redirectPath = $c->getServer()->getURLGenerator()->linkToRoute('myapp.page.validate');
$refererPath = path($_SERVER['HTTP_REFERER']);
if ( $requestedPath !== $redirectPath && $redirectPath !== $refererPath ) {
$location = $c->getServer()->getRouter()->generate('myapp.page.validate');
header('Location: ' . $location);
exit();
}
}
function path($url) {
$urlArray = parse_url($url);
return $urlArray['path'];
}
It works fine for the first case, but I go into several redirections in the second case.
I think it must exist a better solution. Somebody has an idea ?
PS: I have exposed my case on IRC channel without success to interest someone :)
You might be able to do this using appinfo/app.php if you've registered your app as type authentication in appinfo/info.xml. This should basically look like the following code, however this obviously needs further tuning for your use-case.
info.xml:
<?xml version="1.0"?>
<info>
<id>appname</id>
<name>Appname</name>
<description>Lorem Ipsum.</description>
<licence>AGPL</licence>
<author>Your Name</author>
<require>6.0.3</require>
<types>
<authentication/>
</types>
</info>
app.php:
<?php
namespace OCA\appname\AppInfo;
use \OCP\User;
/**
* Implement your code here
* #return bool
*/
function conditionMatch() {
return true;
}
// Intercept all requests which have not already been matched
if ($_SESSION['alreadyMatched'] !== true) {
if(conditionMatch()) {
$_SESSION['alreadyMatched'] = true;
} else {
// The session has not met the condition - enter your code here
exit();
}
}

Fatal error: in base_facebook.php on line 1039

I am getting the following error
Uncaught OAuthException: An active access token must be used to query information about the current user.
My frame application consists of two pages - index.php and index1.php. By default when index.php loads, it has following link to index1.php at the top:
index1
and also the following code:
<?PHP
include("facebook.php");
$config = array();
$config['appId'] =$appId;
$config['secret'] = $appSecret;
$fb = new Facebook($config);
$access_token = $fb->getAccessToken();
$user_profile = $fb->api('/me','GET');
$userid = $fb->getUser();
?>
index1.php has same code at the top as index.php is has.
When I load application it doesn't give any error and loads perfectly, but when I click on link to index1.php it gives
Uncaught OAuthException: An active access token must be used to query information about the current user in base_facebook.php at 1039
How can I fix this?
You probably don't have an active access token. To get one, the user must authorize your app and log in. You might try to var_dump($access_token) -- I suspect you may find it returns null or false
You might try something like
if(($access_token = $fb->getAccessToken()) && ($userid = $fb->getUser())) {
$user_profile = $fb->api('/me','GET');
}