I've been trying to implement openID authentication as a consumer in a project I'm developing, and I haven't yet managed to make even the examples work as I want.
Even though the example consumer works perfectly for yahoo openid authentication, it fails in the try_auth.php page with a 501 HTTP error when trying to use google openID.
Here's the code for try_auth.php (the page that handles the call to the actual openID provider):
<?php
error_reporting(E_ALL);
ini_set('display_errors','On');
require_once "common.php";
session_start();
function getOpenIDURL() {
// Render a default page if we got a submission without an openid
// value.
if (empty($_GET['openid_identifier'])) {
$error = "Expected an OpenID URL.";
include 'index.php';
exit(0);
}
return $_GET['openid_identifier'];
}
function run() {
$openid = getOpenIDURL();
$consumer = getConsumer();
// Begin the OpenID authentication process.
$auth_request = $consumer->begin($openid);
// No auth request means we can't begin OpenID.
if (!$auth_request) {
displayError("Authentication error; not a valid OpenID.");
}
$sreg_request = Auth_OpenID_SRegRequest::build(
// Required
array('nickname'),
// Optional
array('fullname', 'email'));
if ($sreg_request) {
$auth_request->addExtension($sreg_request);
}
$policy_uris = null;
if (isset($_GET['policies'])) {
$policy_uris = $_GET['policies'];
}
$pape_request = new Auth_OpenID_PAPE_Request($policy_uris);
if ($pape_request) {
$auth_request->addExtension($pape_request);
}
// Redirect the user to the OpenID server for authentication.
// Store the token for this authentication so we can verify the
// response.
// For OpenID 1, send a redirect. For OpenID 2, use a Javascript
// form to send a POST request to the server.
if ($auth_request->shouldSendRedirect()) {
$redirect_url = $auth_request->redirectURL(getTrustRoot(),
getReturnTo());
// If the redirect URL can't be built, display an error
// message.
if (Auth_OpenID::isFailure($redirect_url)) {
displayError("Could not redirect to server: " . $redirect_url->message);
} else {
// Send redirect.
header("Location: ".$redirect_url);
}
} else {
// Generate form markup and render it.
$form_id = 'openid_message';
$form_html = $auth_request->htmlMarkup(getTrustRoot(), getReturnTo(),
false, array('id' => $form_id));
// Display an error if the form markup couldn't be generated;
// otherwise, render the HTML.
if (Auth_OpenID::isFailure($form_html)) {
displayError("Could not redirect to server: " . $form_html->message);
} else {
print $form_html;
}
}
}
run();
?>
Another think I noticed is that on my windows dev box (Apache 2.2.6 standalone, not XAMPP, PHP 5.3.8) everything runs smoothly, both yahoo and Google perform openID authentication without any issues.
Anyone have an idea what might be wrong?
Thanks in advance.
After some trial and error, I came to the conclusion that the 501 error occurs due to the Google openID url being passed to the page either as querystring (for form method "get") either as postdata (for form method "post"). In particular, the url I was using is
https://www.google.com/accounts/o8/id
the last part (the "id") is triggering the 501 error. If I use
https://www.google.com/accounts/o8/id/
the error is not triggered. Well, since the two are equivalent urls, I'll be using the second one. I'm still curious as to why this was happening though.
Related
I'm trying to get the FB Messenger Bot API to work. I'm currently on the step where I'm trying to subscribe a webhook. I currently have a script of the following form:
#!/usr/bin/php
<?php
$challenge = $_REQUEST['hub_challenge'];
echo $challenge; # HERE!
$verify_token = $_REQUEST['hub_verify_token'];
if ($verify_token === 'token') {
echo $challenge;
}
?>
However when I try to "Verify and Save" the callback URL I get an error of the form:
The URL couldn't be validated. Response does not match challenge, expected value = '401537941', received=''
namely that my script is sending an empty string. However, if I change the line marked "HERE!" above to "echo 'cat' ", the error message is the same except "received='cat'" as expected. Thus, my script is being executed and is trying to send some content back to FB, but for some reason the $challenge variable is empty. Why could this be the case?
Thanks!
if($_GET['hub_verify_token'] === "validation_token"){
echo($_GET["hub_challenge"]);
} else {
echo("error");
}
There are probably extra string in your response as you are not exiting after printing challenge. Try your script in browser and inspect html to see if there is anything extra.
Use the following code as you would need to seperate verification code from your work webhook calls. Also verify token is not something you create from Facebook, its your own keyword
/* validate verify token needed for setting up web hook */
if (isset($_GET['hub_verify_token'])) {
if ($_GET['hub_verify_token'] === 'YOUR_SECRET_TOKEN') {
echo $_GET['hub_challenge'];
return;
} else {
echo 'Invalid Verify Token';
return;
}
}
So in this case your verify token is YOUR_SECRET_TOKEN, now when you are setting up web hook, Type YOUR_SECRET_TOKEN in the verification token.
I wrote recently a step by step guide with screen shots here.
I am trying to authenticate with a family history web service that authenticates using OAuth2. The basic workflow of the authentication is that I submit a get request against the web service requesting an authentication session. It returns in the body of the response HTML Code with some login components for user name and password. My PHP application then echoes the html code to the browser. The end user can then enter his or her user name and password, then submit to the web service. This is where the behavior becomes unclear. In theory, The web service should redirect to a predefined redirect URI with some parameters included in the URL. In practice, however, submitting the password redirects to the pre registered redirect URI, but there are no parameters included in the URL. My Project is written primarily in PHP. This is a snippit of the code that makes the inital request for an authentication session.
function logOn($mainURL, $credentials)
{
// create a new HTTP_Request object to be used in the login process
$request = new HTTP_Request();
// set the URL of the HTTP_Request object to the family search identity/login endpoint
$request->setUrl("https://web-service/authentication/path?response_type=code&client_id=".$credentials['key']."&redirect_uri=https://www.myredirectPage.edu/");
$request->_useBrackets = false;
$request->addHeader("User-Agent", $credentials['agent']);
$request->addHeader("Accept","text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8");
$request->sendRequest();
//HTML_HEADER;
//the response will come in the form of an html file
$responseHtml = $request->getResponseBody();
//Dynamically load html from request body onto the browser to allow for authentication
echo $responseHtml;
return $credentials;
}
The end user will enter their login credentials using the loaded html components and hit submit. The web service then redirects to my redirect authentication page. The code there is provided below.
<?php
// process client request (Via url)
//gather code parameters from the redirect url.
if (isset($_GET['code']))
{
echo $_GET['code'];
}
else
{
echo "code not returned";
}
if (isset($_GET['error']))
{
echo $_GET['error'];
}
else
{
echo "error not returned";
}
?>
Thanks in advance to any help with this.
When I use Google Chrome's Network debugger tool, I saw that my project was making unexpected searches for Javascript and Css resources, all resulting in 404 (not found) errors. Upon closer inspection, I could see that the resources were relative paths to resources that are on the web service server. Rather than looking for 'https://webService.net/js/importantJavascript.js' (an existing file located on the service's web server), it was trying to find 'https://mywebpage.edu/js/importantJavascript.js'(a path to a file that doesn't exist).
Hi got a bit problem and I can't find any lead, here it goes
I'm working with OAuth2-client from here and I'm doing it in codeigniter
this is my controller :
public function index()
{
include(APPPATH.'libraries/League/OAuth2/Client/Provider/IdentityProvider.php');
include(APPPATH.'libraries/League/OAuth2/Client/Provider/Google.php');
$provider = new League\OAuth2\Client\Provider\Google(array(
'clientId' => '********************.apps.googleusercontent.com',
'clientSecret' => '**************************',
'redirectUri' => '**************************/oauth2callback'
));
if ( ! isset($_GET['code'])) {
// If we don't have an authorization code then get one
$provider->authorize();
} else {
try {
// Try to get an access token (using the authorization code grant)
$t = $provider->getAccessToken('authorization_code', array('code' => $_GET['code']));
// NOTE: If you are using Eventbrite you will need to add the grant_type parameter (see below)
// $t = $provider->getAccessToken('authorization_code', array('code' => $_GET['code'], 'grant_type' => 'authorization_code'));
try {
// We got an access token, let's now get the user's details
$userDetails = $provider->getUserDetails($t);
foreach ($userDetails as $attribute => $value) {
var_dump($attribute, $value) . PHP_EOL . PHP_EOL;
}
} catch (Exception $e) {
// Failed to get user details
}
} catch (Exception $e) {
// Failed to get access token
}
}
}
I get the OAuth class and save it to my library folder
Somehow I manage to open the google "Choose Account" or "login" and the request for permission this
but when I click Accept the page reload to this url https://mysite.com/oauth2callback?state=****&code=***
and that is 404 in my end.
does anyone have better solution to this, could anyone help me.
this is my 1st try using OAUTH and working in google app engine so please spare me. Thanks in advance.
When the user approves the OAuth, Google redirects back to your app with the URL you registered with them, in your case this is /oauth2callback (this is actually the default). It looks as though, from the code you have posted, that the code to deal with this request is in the index() function.
So, to fix you code, you can either move the logic from the index function to a new handler / controller which responds to /oauth2callback, or change the redirectUri, both in your code and at google cloud console to point back to whatever URL calls the index() function.
404 mean you dont have "oauth2callback" controller or dont have index method in it
callback url is url you can get information requested to oauth provider
I see your url dont have index.php. If normal url of your project have it, you are putting wrong url. Solution is you need to put absolute callback url in callback param by using site_url function
There is a bug in the library, look at this: https://github.com/thephpleague/oauth2-client/issues/90
Anyway, i have the same problem: don't know how to code the callback controller.
I have this application with the below structure
I am using rest client library https://github.com/philsturgeon/codeigniter-restclient to connect to MyAPI and using php api client http://code.google.com/p/google-api-php-client/ to connect to Google API
my Controller code is as below
function index()
{
if($this->form_validation->run())
{
$logged = $this->rest->get('auth/user',array(
'email'=>$this->input->post('email')
));
var_dump($logged);
}
$this->load->view('layout/login',$this->data);
}
and my API code that handle this request is as below which make sure that user exist in my database and authenticated through Google as well
function user_get()
{
$response=NULL;
$data=array(
'email'=>$this->get('email')
);
$google_account=$this->google->authenticate();
if( isset($google_account) && $this->user_model->login($data))
{
$response->status='success';
$response->message=$google_account;
}
else
{
$response->status='error';
$response->message='Failed to authenticate user';
}
$this->response($response,200);
}
and Google library function `Authenticate' is as below
function authenticate()
{
$oauth2 = new Google_Oauth2Service($this->client);
if (isset($_GET['code']))
{
$this->client->authenticate($_GET['code']);
$_SESSION['token'] = $this->client->getAccessToken();
$redirect = 'http://' . $_SERVER['HTTP_HOST'] . $_SERVER['PHP_SELF'];
header('Location: ' . filter_var($redirect, FILTER_SANITIZE_URL));
return;
}
if (isset($_SESSION['token']))
{
$this->client->setAccessToken($_SESSION['token']);
}
if (isset($_REQUEST['logout']))
{
unset($_SESSION['token']);
$this->client->revokeToken();
}
if ($this->client->getAccessToken())
{
$user = $oauth2->userinfo->get();
// The access token may have been updated lazily.
$_SESSION['token'] = $this->client->getAccessToken();
return $user;
}
else
{
$authUrl = $this->client->createAuthUrl();
redirect($authUrl);
}
}
problem is
When i connect this throught browser with direct url
http://localhost/hac_dc/api/auth/user/ahmed.samy.cs#gmail.com
i get JSON response perfectly
but when i connect it using rest client
i get response false I have tried change the way i use my rest client i tried to add third parameter as JSON and as MIME application/json but didnt work out
I dunno if it's problem or bad practice to connect another REST API though my REST API,
been pulling my hair for hours please help me on this
Your REST client doesn't handle the oauth authentication, does it?
I assume you shall authenticate your REST client somehow to let it use the access token delivered by Google.
To do so manually, you might save once the access token you've received from Google to a datastore when accessing your API manually (using your browser for instance and by inspecting your browser session). Having this access token available, you could then restore a valid session for your REST client.
Authenticating your REST client towards Google, can be done using cURL or reusing some existing library such as https://github.com/philsturgeon/codeigniter-oauth2.git. To authenticate your REST client towards your own API, you could use HTTP basic/digest authentication (as suggested by CodeIgniter-REST client) after having added an authentication extra-layer to your api (if it is missing).
P.S. When authenticating your user, in case of failure, the 401 response status code might be more legit (see also http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html#sec10.4.2)
problem is cross domain request error. You can connect
localhost/hac_dc/api/auth/user/ahmed.samy.cs#gmail.com
because your server performs as web proxy. but you can't do it directly via REST with simple getJSON technique. you can use JSONP in jquery ajax,it's 100% working for cross domain. JSONP is not JSON, it returns js function call to callback method with JSON parameter.you can achieve in following ajax call. But there is no 'success' callback in JSONP and for this purpose you must supply callback parameter in ajax call and define that callback function.
$.ajax({
crossDomain: true,
type:"GET",
contentType: "text; charset=utf-8",
url: YOUR_URL + "&callback=mycallback",
jsonp:'jsonp',
dataType: "jsonp"
});
function mycallback(result){
//your callback operation
}
When I sent an authsub request, google says the url is not correct.
I'm suspecting this is because I have a subdomain in my url.
The url that sends the request is http://admin.domain.com/test.php
In php, I put this line of code in the $next variable : '
http://'.$_SERVER['HTTP_HOST'].$_SERVER['REQUEST_URI'];
When I echo it, it shows the proper url but google tells me this :
The page you have requested cannot be displayed. Another site was
requesting access to your Google Account, but sent a malformed
request. Please contact the site that you were trying to use when you
received this message to inform them of the error. A detailed error
message follows:
The page you have requested cannot be displayed. Another site was requesting access to your Google Account, but sent a malformed request. Please contact the site that you were trying to use when you received this message to inform them of the error.
A detailed error message follows: The site "http://domain.com" has not been registered.
Where is my problem ?
Thanks,
Etienne NOEL
EDIT1:
Here's my code: I followed all the instructions and the error still remains:
session_start();
require_once 'lib/Zend/Loader.php';
set_include_path($_SERVER['DOCUMENT_ROOT'].'/lib/');
Zend_Loader::loadClass('Zend_Gdata');
Zend_Loader::loadClass('Zend_Gdata_ClientLogin');
Zend_Loader::loadClass('Zend_Gdata_Calendar');
Zend_Loader::loadClass('Zend_Http_Client');
Zend_Loader::loadClass('Zend_Gdata_Query');
Zend_Loader::loadClass('Zend_Gdata_AuthSub');
$my_calendar = 'http://www.google.com/calendar/feeds/default/private/full';
if (!isset($_SESSION['cal_token'])) {
if (isset($_GET['token'])) {
// You can convert the single-use token to a session token.
$session_token =
Zend_Gdata_AuthSub::getAuthSubSessionToken($_GET['token']);
// Store the session token in our session.
$_SESSION['cal_token'] = $session_token;
} else {
// Display link to generate single-use token
$googleUri = Zend_Gdata_AuthSub::getAuthSubTokenUri(
'http://'. $_SERVER['SERVER_NAME'] . $_SERVER['REQUEST_URI'],
$my_calendar, 0, 1);
echo "Click <a href='$googleUri'>here</a> " .
"to authorize this application.";
exit();
}
}
// Create an authenticated HTTP Client to talk to Google.
$client = Zend_Gdata_AuthSub::getHttpClient($_SESSION['cal_token']);
// Create a Gdata object using the authenticated Http Client
$cal = new Zend_Gdata_Calendar($client);