I implement OAUTH authentication. I'm sending a POST request to an API. But something is wrong in my code. I get error 404 back. can someone help me. this API does not support ClientSecret.
this is my Code
<?php
$callback_uri = "http://localhost/zeiterfassung/" ;
$client_id = "2371031349-3075189699-483870032-1896673008" ;
$code = $_GET['code'];
$resourc = "http://localhost/zeiterfassung/";
if (isset($_GET['code'])) {
// try to get an access token
$code = $_GET['code'];
$url = 'https://adfs3int.fds.metro.info/oauth2/token';
$params = array(
"code" => $code,
"client_id" => $client_id,
"redirect_uri" => 'http://' . $_SERVER["HTTP_HOST"] . $_SERVER["PHP_SELF"],
"grant_type" => "authorization_code"
);
$ch = curl_init();
curl_setopt($ch, constant("CURLOPT_" . 'URL'), $url);
curl_setopt($ch, constant("CURLOPT_" . 'POST'), true);
curl_setopt($ch, constant("CURLOPT_" . 'POSTFIELDS'), $params);
$output = curl_exec($ch);
$info = curl_getinfo($ch);
curl_close($ch);
if ($info['http_code'] === 200) {
header('Content-Type: ' . $info['content_type']);
return $output;
} else {
return 'An error happened';
}
} else {
$url = "https://adfs3int.fds.metro.info/adfs/oauth2/authorize";
$params = array(
"response_type" => "code",
"client_id" => $client_id,
"redirect_uri" => $callback_uri,
"resource" => $resourc
);
$request_to = $url . '?' . http_build_query($params);
header("Location: " . $request_to);
}
?>
404 is a client site error and say's that you have done something wrong - it means that what you are looking for is not there where are you looking.
It's like, you searching socks in you closet but you cant find the socks cause your socks aren't in the closet.
I looks like the requesting api is hosted on your localhost, maybe the api is in an ohter folder?
Related
I'm trying to create a sign in system using disocrd's oauth2.
This is my code:
<?php
ini_set('display_errors', 1);
ini_set('display_startup_errors', 1);
ini_set('max_execution_time', 300); //300 seconds = 5 minutes. In case if your CURL is slow and is loading too much (Can be IPv6 problem)
error_reporting(E_ALL);
define('OAUTH2_CLIENT_ID', 'XXXXXXXXXXXXXXXXXXXXXX'); //Your client Id
define('OAUTH2_CLIENT_SECRET', 'XXXXXXXXXXXXXXXXXXXXXX'); //Your secret client code
$authorizeURL = 'https://discordapp.com/api/oauth2/authorize';
$tokenURL = 'https://discordapp.com/api/oauth2/token';
$apiURLBase = 'https://discordapp.com/api/users/#me';
session_start();
// Start the login process by sending the user to Discord's authorization page
if(get('action') == 'login') {
// Redirect the user to Discord's authorization page
header('Location: https://discord.com/api/oauth2/authorize?client_id=873917693953191946&redirect_uri=http%3A%2F%2Fbouncerbot.go-atcode.com%2Fauth.php&response_type=code&scope=identify%20email%20connections%20guilds%20gdm.join%20guilds.join%20rpc%20rpc.notifications.read%20rpc.voice.read%20rpc.voice.write');
die();
}
// When Discord redirects the user back here, there will be a "code" and "state" parameter in the query string
if(get('code')) {
$token = apiRequest($tokenURL, array(
"grant_type" => "authorization_code",
'client_id' => 'XXXXXXXXXXXXXXXX', //censored
'client_secret' => 'XXX-XXXXXXXXXXXXXXXXXXX',
'redirect_uri' => 'http://bouncerbot.go-atcode.com/auth.php',
'code' => get('code')
));
$logout_token = $token->access_token;
$_SESSION['access_token'] = $token->access_token;
header('Location: ' . $_SERVER['PHP_SELF']);
}
?><script> console.log(<? echo $user->username?> )</script><?
if(session('access_token')) {
$user = apiRequest($apiURLBase);
echo '<h3>Logged In</h3>';
echo '<h4>Welcome, ' . $user->username . '</h4>';
echo '<pre>';
print_r($user);
echo '</pre>';
} else {
echo '<h3>Not logged in</h3>';
echo '<p>Log In</p>';
}
if(get('action') == 'logout') {
// This must to logout you, but it didn't worked(
$params = array(
'access_token' => $logout_token
);
// Redirect the user to Discord's revoke page
header('Location: https://discordapp.com/api/oauth2/token/revoke' . '?' . http_build_query($params));
die();
}
function apiRequest($url, $post=FALSE, $headers=array()) {
$ch = curl_init($url);
curl_setopt($ch, CURLOPT_IPRESOLVE, CURL_IPRESOLVE_V4);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, TRUE);
$response = curl_exec($ch);
if($post)
curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query($post));
$headers[] = 'Accept: application/json';
if(session('access_token'))
$headers[] = 'Authorization: Bearer ' . session('access_token');
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
$response = curl_exec($ch);
return json_decode($response);
}
function get($key, $default=NULL) {
return array_key_exists($key, $_GET) ? $_GET[$key] : $default;
}
function session($key, $default=NULL) {
return array_key_exists($key, $_SESSION) ? $_SESSION[$key] : $default;
}
?>
The problem is that when I go to authorize on discord and then discord redirects me back to auth.php, the token is not fetched and therefore remains:
Not logged in Log In
I couldn't figure out the cause of the problem so I asked a question. This is the login page: http://bouncerbot.go-atcode.com/auth.php
1st) Redirection is working fine because you are using
'redirect_uri' => 'http://bouncerbot.go-atcode.com/auth.php',
That's why to redirect to auth.php
2nd) You have to define the same redirection URL on discord application like this:
3rd) Create a code generation page and redirection page, you can either both on same page or you can create both seprate pages.
As I am testing with creating 2 pages
1. The request for code (disocrd.php)
<?php
define('OAUTH2_CLIENT_ID', '882143362046640112');
$redirectURL = 'https://localhost/test_project/disocrd_responce.php';
$params = array(
'client_id' => OAUTH2_CLIENT_ID,
'redirect_uri' => $redirectURL,
'response_type' => 'code',
'scope' => 'identify guilds'
);
// Redirect the user to Discord's authorization page
header('Location: https://discord.com/api/oauth2/authorize' . '?' . http_build_query($params));
die();
?>
After hit this page, the page will auto-redirect to https://localhost/test_project/disocrd_responce.php with code
2. Generate token by using code (disocrd_responce.php)
<?php
ini_set('display_errors', 1);
ini_set('display_startup_errors', 1);
ini_set('max_execution_time', 300); //300 seconds = 5 minutes. In case if your CURL is slow and is loading too much (Can be IPv6 problem)
error_reporting(E_ALL);
$code = isset($_REQUEST['code']) ? $_REQUEST['code'] : '';
define('OAUTH2_CLIENT_ID', '882143362046640112');
define('OAUTH2_CLIENT_SECRET', 'hYvpAl_heUJNC0veaoraMxNhJL2fgHVU');
$authorizeURL = 'https://discord.com/api/oauth2/authorize';
$tokenURL = 'https://discord.com/api/oauth2/token';
$redirectURL = 'https://localhost/test_project/disocrd_responce.php';
if(get('code')) {
session_start();
// Exchange the auth code for a token
$token = apiRequest($tokenURL, array(
"grant_type" => "authorization_code",
'client_id' => OAUTH2_CLIENT_ID,
'client_secret' => OAUTH2_CLIENT_SECRET,
'redirect_uri' => $redirectURL,
'code' => get('code')
));
$logout_token = $token->access_token;
$_SESSION['access_token'] = $token->access_token;
echo "<pre>"; print_r($token); exit; // get token properly
// header('Location: ' . $_SERVER['PHP_SELF']);
}
function apiRequest($url, $post=FALSE, $headers=array()) {
$ch = curl_init($url);
curl_setopt($ch, CURLOPT_IPRESOLVE, CURL_IPRESOLVE_V4);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, TRUE);
$response = curl_exec($ch);
if($post){
curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query($post));
}
$headers[] = 'Accept: application/json';
if(isset($_SESSION['access_token']))
$headers[] = 'Authorization: Bearer ' . $_SESSION['access_token'];
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
$response = curl_exec($ch);
return json_decode($response);
}
function get($key, $default=NULL) {
return array_key_exists($key, $_GET) ? $_GET[$key] : $default;
}
?>
When I print tokens like this:
echo "<pre>"; print_r($token); exit;
We got token properly like this:
stdClass Object
(
[access_token] => 'FBLOYotKRxe0uO7KJcS8mfce5z9YEE'
[expires_in] => 604800
[refresh_token] => FxlsNH06OHcbMCJlAZhWzbi4DsIjUO
[scope] => identify guilds
[token_type] => Bearer
)
Note: I have a change customer id and token by security point of view
You get the answer in the redirect URL when you test it:
http://bouncerbot.go-atcode.com/auth.php?error=invalid_scope&error_description=The+requested+scope+is+invalid%2C+unknown%2C+or+malformed.
Try only ask for email and see if it works. If it does keep adding stuff until you find what causes the issue.
I am using the following code to access an OpenId system and request a bearer token.
if (isset($_GET['code'])) {
// try to get an access token
$code = $_GET['code'];
$url = 'https://3rdpartydomain.com/connect/token';
$params = array(
"code" => $code,
"client_id" => CLIENTID,
"client_secret" => CLIENTSECRET,
"redirect_uri" => 'http://' . $_SERVER["HTTP_HOST"] . $_SERVER["PHP_SELF"],
"grant_type" => "authorization_code"
);
$ch = curl_init();
curl_setopt($ch, constant("CURLOPT_" . 'URL'), $url);
curl_setopt($ch, constant("CURLOPT_" . 'POST'), true);
curl_setopt($ch, constant("CURLOPT_" . 'POSTFIELDS'), $params);
$output = curl_exec($ch);
$info = curl_getinfo($ch);
curl_close($ch);
if ($info['http_code'] === 200) {
header('Content-Type: ' . $info['content_type']);
return $output;
} else {
return 'An error happened';
}
} else {
$url = "https://3rdpartydomain.com/connect/token";
$params = array(
"response_type" => "code",
"client_id" => CLIENTID,
"redirect_uri" => 'http://' . $_SERVER["HTTP_HOST"] . $_SERVER["PHP_SELF"],
"scope" => "openid"
);
$request_to = $url . '?' . http_build_query($params);
header("Location: " . $request_to);
}
However, I'm getting the following message:
{"Message":"The requested resource does not support http method 'GET'."}
Can someone help identify the correct to my code please?
Thanks!
Add these:
curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, false);
curl_setopt($curl, CURLOPT_SSL_VERIFYHOST, false);
There is probably a change of requested method in the redirect from your IdP. I've seen this issue when I was testing my OIDC with curl -XPOST. The workaround was to remove that request type specification. Try to comment your line: curl_setopt($ch, constant("CURLOPT_" . 'POST'), true);
I am creating a web application that requires Google OAuth authentication.
I have successfully recieved the refresh and access token, however, I cannot seem to get the refresh token again.
I understand that I need to revoke access from my account in order to get the refresh token again. However this does not seem to work on the multiple accounts that I have tested this on.
login.php
<?php
$url = "https://accounts.google.com/o/oauth2/auth";
$params = array(
"response_type" => "code",
"client_id" => "xxxx.apps.googleusercontent.com",
"redirect_uri" => "http://xxxx.net/auth/callback",
"scope" => "https://www.googleapis.com/auth/plus.me"
);
$request_to = $url . '?' . http_build_query($params);
header("Location: " . $request_to);
?>
callback.php
<?php
$url = "https://accounts.google.com/o/oauth2/auth";
$client_id = xxxx.apps.googleusercontent.com";
$client_secret = "xxxx";
$redirect_uri = "http://xxxx.net/auth/callback";
$access_type = "offline";
$approval_prompt = "force";
$grant_type = "authorization_code";
$scope = "https://www.googleapis.com/auth/plus.me";
$params_request = array(
"response_type" => "code",
"client_id" => "$client_id",
"redirect_uri" => "$redirect_uri",
"access_type" => "$access_type",
"approval_prompt" => "$approval_prompt",
"scope" => "$scope"
);
$request_to = $url . '?' . http_build_query($params_request);
if(isset($_GET['code'])) {
// try to get an access token
$code = $_GET['code'];
$url = 'https://accounts.google.com/o/oauth2/token';
$params = array(
"code" => $code,
"client_id" => "$client_id",
"client_secret" => "$client_secret",
"redirect_uri" => "$redirect_uri",
"grant_type" => "$grant_type"
);
$curl = curl_init($url);
curl_setopt($curl, CURLOPT_POST, true);
curl_setopt($curl, CURLOPT_POSTFIELDS, $params);
curl_setopt($curl, CURLOPT_HTTPAUTH, CURLAUTH_ANY);
curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, false);
curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);
$json_response = curl_exec($curl);
curl_close($curl);
$authObj = json_decode($json_response);
echo "Refresh token: " . $authObj->refresh_token;
echo "Access token: " . $authObj->access_token;
exit("Done.");
}
header("Location: " . $request_to);
?>
Within callback.php, I have attempted to modify the $params_request array to include the arrival_prompt="force" configuration, which is supposed to require user authentication and return the refresh token. However this does not work for me either.
I have even went as far as to regenerate the client ID, revoke access from my account, clear my cache, and reattempt connection, yet still only recieve the access token! What is wrong? Could someone please provide me with a solution and a way to consistently get back the refresh token.
Thank you in advance for your help and time.
To get a new refresh token for your client you first need to revoke the existing/old refresh token by revoking access for your client in the Account Permissions tab for your Google account and then ask for access_type=offline again. Revoking access for clients is done here: https://security.google.com/settings/security/permissions?pli=1
I have a little problem with my FB application. It's about that I always get error:
{"error":{"message":"(#353) Missing video file","type":"OAuthException","code":353}}
with this code:
$post_url = "https://graph-video.facebook.com/xxx/videos?"
. "title=" . $video_title . "&description=" . $video_desc
. "&access_token=" . $access_token;
$ch = curl_init();
$data = array(
'source' => 'http://x/upload/' . $name . '.' . $type,
'file' => './upload/' . $name . '.' . $type,
'type' => 'avi',
);
curl_setopt($ch, CURLOPT_URL, $post_url);
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, $data);
$response = curl_exec($ch);
if (!$response)
{
print_r(Debug::vars(array(curl_error($ch), curl_errno($ch))));
}
curl_close($ch);
File exist, access_token is valid and is logged as a app, In $data I've tried set only 'file' or 'source' but effects was the same.
You are best off using the Facebook PHP SDK for this, but it might be as simple as removing your file param and adding "#" to your source path. Here is a working example with the SDK (assuming you have asked for the appropriate FB permissions):
$this->facebook->setFileUploadSupport(true);
$upload = $this->facebook->api('/me/videos', 'POST', array(
'source' => '#'.$file,
'title' => $title,
'description' => $description
));
I found this function that supposedly gets the accessToken, but I get nothing.
I do have the $_REQUEST['code'], and the other information needed in this function.
Any ideas what is wrong here?
Thanks.
//Oauth 2.0: exchange token for session token so multiple calls can be made to api
if(isset($_REQUEST['code'])){
$_SESSION['accessToken'] = get_oauth2_token($_REQUEST['code']);
}
//returns session token for calls to API using oauth 2.0
function get_oauth2_token($code) {
global $client_id;
global $client_secret;
global $redirect_uri;
$oauth2token_url = "https://accounts.google.com/o/oauth2/token";
$clienttoken_post = array(
"code" => $code,
"client_id" => $client_id,
"client_secret" => $client_secret,
"redirect_uri" => $redirect_uri,
"grant_type" => "authorization_code"
);
$curl = curl_init($oauth2token_url);
curl_setopt($curl, CURLOPT_POST, true);
curl_setopt($curl, CURLOPT_POSTFIELDS, $clienttoken_post);
curl_setopt($curl, CURLOPT_HTTPAUTH, CURLAUTH_ANY);
curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, false);
curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);
$json_response = curl_exec($curl);
curl_close($curl);
$authObj = json_decode($json_response);
if (isset($authObj->refresh_token)){
//refresh token only granted on first authorization for offline access
//save to db for future use (db saving not included in example)
global $refreshToken;
$refreshToken = $authObj->refresh_token;
}
$accessToken = $authObj->access_token;
return $accessToken;
}
This is what I did to get my access token and refresh token.
Create a file that contains the following code :
<?php
if (isset($_GET['code'])) {
// try to get an access token
$code = $_GET['code'];
$url = 'https://accounts.google.com/o/oauth2/token';
$params = array(
"code" => $code,
"client_id" => YOUR_CLIENT_ID,
"client_secret" => YOUR_CLIENT_SECRET,
"redirect_uri" => 'http://' . $_SERVER["HTTP_HOST"] . $_SERVER["PHP_SELF"],
"grant_type" => "authorization_code"
);
$ch = curl_init();
curl_setopt($ch, constant("CURLOPT_" . 'URL'), $url);
curl_setopt($ch, constant("CURLOPT_" . 'POST'), true);
curl_setopt($ch, constant("CURLOPT_" . 'POSTFIELDS'), $params);
$output = curl_exec($ch);
$info = curl_getinfo($ch);
curl_close($ch);
if ($info['http_code'] === 200) {
header('Content-Type: ' . $info['content_type']);
return $output;
} else {
return 'An error happened';
}
} else {
$url = "https://accounts.google.com/o/oauth2/auth";
$params = array(
"response_type" => "code",
"client_id" => YOUR_CLIENT_ID,
"redirect_uri" => 'http://' . $_SERVER["HTTP_HOST"] . $_SERVER["PHP_SELF"],
"scope" => "https://www.googleapis.com/auth/plus.me"
);
$request_to = $url . '?' . http_build_query($params);
header("Location: " . $request_to);
}
Now, replace YOUR_CLIENT_ID and YOUR_CLIENT_SECRET with your client ID and client secret.
Make sure your scope is correct. For example, it should be https://www.googleapis.com/auth/analytics if you want to get access to Analytics.
If you run the file, you should get an OAuth2 approval screen.
If you now press Accept, you should get a result that looks like this:
{
"access_token" : YOUR_ACCESS_TOKEN,
"token_type" : "Bearer",
"expires_in" : 3600,
"refresh_token" : YOUR_REFRESH_TOKEN
}
The result may contain additional fields, depending on which scope you're applying for.
I don't see anything wrong with your code, but you may want to try refreshing the client secret and see if that helps. Additionally, I would suggest you see exactly what the response is coming back from your curl command, I suspect it's "invalid_grant".
A much better way to do this is to use google's php api client:
https://code.google.com/p/google-api-php-client/
which handles most of the communication for you. The examples there are very easy to use. It mostly depends on which google service you are trying to access.
that code looks familiar - I'm using roughly the same code - there are two things you can try.
Use echo to echo the response to the Browser
echo $json_response;
Get hold of Fiddler and use the following line before the call to curl_exec
curl_setopt($curl, CURLOPT_PROXY, '127.0.0.1:8888');
'fraid I've not got it working either - the response I am getting is
{
"error" : "invalid_request"
}
Now if anyone knows how what is wrong with this ;)
From section 4.4.2 of "The OAuth 2.0 Authorization Protocol draft-ietf-oauth-v2-20"
The client makes a request to the token endpoint by adding the
following parameters using the "application/x-www-form-urlencoded"
format in the HTTP request entity-body:
So the POSTed parameters should be submitted in the form of a string, not an array. This is mentioned in the PHP manual for curl_setopt too.
So instead of posting $clienttoken_post, you might want to post http_build_query($clienttoken_post,'','&').
This might not solve all your problems, but it's probably a step in the right direction.
I had the same error, and I found that adding
curl_setopt($curl, CURLOPT_FOLLOWLOCATION, 1);
to allow the request follow a redirect solved it quickly. I hope that helps someone else!