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);
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 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?
I have website created in PHP. Basically it is a send document kind of project. It uses a document store in Azure I will call and send it into Azure. Now I want to send in email as well as store in Google drive.
So it should be stored to drive with public access. I have create following code. It works properly I don't want any input from user.
$client->setAccessToken($_SESSION['accessToken']);
$service = new Google_DriveService($client);
$finfo = finfo_open(FILEINFO_MIME_TYPE);
$file = new Google_DriveFile();
foreach ($files as $file_name) {
$file_path = 'files/'.$file_name;
$mime_type = finfo_file($finfo, $file_path);
$file->setTitle($file_name);
$file->setDescription('This is a '.$mime_type.' document');
$file->setMimeType($mime_type);
$service->files->insert(
$file,
array(
'data' => file_get_contents($file_path),
'mimeType' => $mime_type
)
);
}
finfo_close($finfo);
I want upload from Azure URL using cURL or using API. When mail send it is automatically uploaded to drive at the same time.
Question Update
I have function to send a mail this is work perfectly. I would like to store an attachment to google drive and retrieve path store that path in to database.
This all work will be based on API no user interaction required. That file is PDF in formate and not specific bytes its different as per data of file.
Issue :
When I upload a file to Drive original file name is rename to untitled. Here is code.
function uploadFile($credentials, $filename, $targetPath)
{
global $GAPIS;
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $GAPIS . 'upload/drive/v2/files?uploadType=media');
curl_setopt($ch, CURLOPT_BINARYTRANSFER, 1);
//curl_setopt($ch, CURLOPT_POSTFIELDS, array("title" =>"newfile.txt"));
curl_setopt($ch, CURLOPT_POSTFIELDS, file_get_contents($filename));
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_HTTPHEADER,
array('Content-Type : text/plain', 'Content-Length:' . filesize($filename),
'Authorization: Bearer ' . getAccessToken($credentials))
);
$postResult = curl_exec($ch);
curl_close($ch);
return json_decode($postResult, true);
}
==========================================
Updated code (Issue with Added code but still getting issue with Untitle.pdf in drive)
==========================================
<?php
$GAPIS = 'https://www.googleapis.com/';
$GAPIS_AUTH = $GAPIS . 'auth/';
$GOAUTH = 'https://accounts.google.com/o/oauth2/';
$CLIENT_ID = '709846732498-xxxxxxxx';
$CLIENT_SECRET = 'XXXXXXXXXXXXXX';
$REDIRECT_URI = 'http' . ($_SERVER['SERVER_PORT'] == 80 ? '' : 's') . '://' . $_SERVER['SERVER_NAME'] . $_SERVER['SCRIPT_NAME'];
$SCOPES = array($GAPIS_AUTH . 'drive', $GAPIS_AUTH . 'drive.file', $GAPIS_AUTH . 'userinfo.email', $GAPIS_AUTH . 'userinfo.profile');
$STORE_PATH = 'credentials.json';
function uploadFile($credentials, $filename, $targetPath)
{
global $GAPIS;
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $GAPIS . 'upload/drive/v2/files?uploadType=media');
curl_setopt($ch, CURLOPT_BINARYTRANSFER, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, file_get_contents($filename));
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_HTTPHEADER,
array('Content-Type : application/pdf', 'Content-Length:' . filesize($filename),
'Authorization: Bearer ' . getAccessToken($credentials))
);
$postResult = curl_exec($ch);
curl_close($ch);
return json_decode($postResult, true);
}
function getStoredCredentials($path)
{
$credentials = json_decode(file_get_contents($path), true);
if (isset($credentials['refresh_token']))
return $credentials;
$expire_date = new DateTime();
$expire_date->setTimestamp($credentials['created']);
$expire_date->add(new DateInterval('PT' . $credentials['expires_in'] . 'S'));
$current_time = new DateTime();
if ($current_time->getTimestamp() >= $expire_date->getTimestamp())
{
$credentials = null;
unlink($path);
}
return $credentials;
}
function storeCredentials($path, $credentials)
{
$credentials['created'] = (new DateTime())->getTimestamp();
file_put_contents($path, json_encode($credentials));
return $credentials;
}
function requestAuthCode()
{
global $GOAUTH, $CLIENT_ID, $REDIRECT_URI, $SCOPES;
$url = sprintf($GOAUTH . 'auth?scope=%s&redirect_uri=%s&response_type=code&client_id=%s&approval_prompt=force&access_type=offline',
urlencode(implode(' ', $SCOPES)), urlencode($REDIRECT_URI), urlencode($CLIENT_ID)
);
header('Location:' . $url);
}
function requestAccessToken($access_code)
{
global $GOAUTH, $CLIENT_ID, $CLIENT_SECRET, $REDIRECT_URI;
$url = $GOAUTH . 'token';
$post_fields = 'code=' . $access_code . '&client_id=' . urlencode($CLIENT_ID) . '&client_secret=' . urlencode($CLIENT_SECRET)
. '&redirect_uri=' . urlencode($REDIRECT_URI) . '&grant_type=authorization_code';
$ch = curl_init();
curl_setopt($ch, CURLOPT_POSTFIELDS, $post_fields);
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_URL, $url);
$result = curl_exec($ch);
curl_close($ch);
return json_decode($result, true);
}
function getAccessToken($credentials)
{
$expire_date = new DateTime();
$expire_date->setTimestamp($credentials['created']);
$expire_date->add(new DateInterval('PT' . $credentials['expires_in'] . 'S'));
$current_time = new DateTime();
if ($current_time->getTimestamp() >= $expire_date->getTimestamp())
return $credentials['refresh_token'];
else
return $credentials['access_token'];
}
function authenticate()
{
global $STORE_PATH;
if (file_exists($STORE_PATH))
$credentials = getStoredCredentials($STORE_PATH);
else
$credentials = null;
if (!(isset($_GET['code']) || isset($credentials)))
requestAuthCode();
if (!isset($credentials))
$credentials = requestAccessToken($_GET['code']);
if (isset($credentials) && isset($credentials['access_token']) && !file_exists($STORE_PATH))
$credentials = storeCredentials($STORE_PATH, $credentials);
return $credentials;
}
$credentials = authenticate();
$result = uploadFile($credentials, 'example.pdf', '');
if (!isset($result['id']))
throw new Exception(print_r($result));
else
echo 'File copied successfuly (file Id: ' . $result['id'] . ')';
echo '<pre>'; print_r($result);
going by https://developers.google.com/drive/api/v3/simple-upload , this should work:
<?php
$ch = curl_init ();
curl_setopt_array ( $ch, array (
CURLOPT_URL => 'https://www.googleapis.com/upload/drive/v3/files?uploadType=media',
CURLOPT_HTTPHEADER => array (
'Content-Type: application/pdf', // todo: runtime detection?
'Authorization: Bearer [YOUR_AUTH_TOKEN]'
),
CURLOPT_POST => 1,
CURLOPT_POSTFIELDS => file_get_contents ( '/path/to/file.pdf' ),
CURLOPT_RETURNTRANSFER => 1
) );
try {
if (false === ($resp = curl_exec ( $ch ))) {
throw new \RuntimeException ( 'curl error ' . curl_errno ( $ch ) . ": " . curl_error ( $ch ) );
}
$parsed = json_decode ( $resp, true );
if (! $parsed || $parsed ['code'] !== 200) {
throw new \RuntimeException ( 'google api error: ' . $resp );
}
} finally{
curl_close ( $ch );
}
var_dump($resp);
I am still not completely sure i understand your question. Assuming you just want to upload a file in php or curl here are two options.
Uploading to Google drive is in two parts the first part you create the meta data that being the file name and basic information about your fine. The second part is where you upload the actual data of your file.
$fileMetadata = new Google_Service_Drive_DriveFile(array(
'name' => 'My Report',
'mimeType' => 'application/vnd.google-apps.spreadsheet'));
$content = file_get_contents('files/report.csv');
$file = $driveService->files->create($fileMetadata, array(
'data' => $content,
'mimeType' => 'text/csv',
'uploadType' => 'multipart',
'fields' => 'id'));
printf("File ID: %s\n", $file->id);
Code ripped from media upload
If you want to do this in curl inserting the meta data shouldnt be an issue your issue will be uploading the file itself. You will need to POST the metadata to create the empty file and capture its file-id. Then use the file-id for a content upload. You can find more information on the requests you will nee dot make here simple upload request.
The code will probably look something like this but again your going to have to pass the file id.
curl
--silent
--request POST
--data-binary "#c:\temp\myfile.jpg"
-OL MyFolder\myfile2.jpeg
-H "Slug: myfile3.jpg"
-H "Authorization: Bearer [your access token here]"
-H "Content-Type: image/jpeg {"fileid":"1234"}"
"https://www.googleapis.com/upload/drive/v3/files?uploadType=media"
Note i have not tested the upload in curl this is just a guess.
You can use Logic Apps to send the file from Azure Blob storage to Google Drive as well as an email attachment.
https://learn.microsoft.com/en-us/azure/connectors/connectors-create-api-azureblobstorage
Alternatively files stored in Azure Blobs can be addresses with a public URL assuming you have the right permissions set on the container and/or blob.
I'm using the following PHP class which I found on GitHub: Twitch oauth class
So I've been creating the Authentification site, which will let you authentificate your twitch account and redirect you to another site using the following url:
http://website.com/twitch/dashboard.php?code=xxxxxxx&scope=user_read+channel_read+chat_login+user_follows_edit+channel_editor+channel_commercial+channel_check_subscription
Now I've used the following code to receive the access_token:
<?php
$ttv_code = $_GET['code'];
$access_token = $twitchtv->get_access_token($ttv_code);
$user_name = $twitchtv->authenticated_user($access_token);
if(isset($user_name)) {
echo 'Thank you ' . $user_name . '! Authentication Completed!';
}else{
echo 'Authentification failed!';
}
?>
But sadly there's no response coming back from the function. The function looks like the following:
function get_access_token($code) {
$ch = curl_init($this->base_url . "oauth2/token");
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, FALSE);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, TRUE);
curl_setopt($ch, CURLOPT_POST, 1);
$fields = array(
'client_id' => $this->client_id,
'client_secret' => $this->client_secret,
'grant_type' => 'authorization_code',
'redirect_uri' => $this->redirect_url,
'code' => $code
);
curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query($fields));
$data = curl_exec($ch);
$response = json_decode($data, true);
return $response["access_token"];
}
Does anyone have a idea what causes this mistake? I would appreciate any kind of help.
I am working with OAuth for the first time and playing around with the Youtube one. I got the following code:
if(isset($_GET['code'])) {
$code = $_GET['code'];
$url = 'https://accounts.google.com/o/oauth2/token';
$params = array(
"code" => $code,
"client_id" => "XXX",
"client_secret" => "YYY",
"redirect_uri" => "URL",
"grant_type" => "authorization_code"
);
$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 "access_token: " . $authObj->access_token;
echo "token_type: " . $authObj->token_type;
echo "expires_in: " . $authObj->expires_in;
echo "refresh_token: " . $authObj->refresh_token;
$msg = '<p class="bg-success msg-padding"><b>Success:</b> You have successfully linked your Youtube account.</p>';
}
if(isset($_GET['error'])) {
$msg = '<p class="bg-danger msg-padding"><b>Error:</b> You have canceled the Youtube account linking process.</p>';
}
How do I obtain the Youtube channels ID, username, subscribers count and such via the access token, if possible at all?
You can use this access token to access other data endpoints in the Data API v3 by specifying mine=true as parameter.
For more info the channel list endpoint, check out the documentation: https://developers.google.com/youtube/v3/docs/channels/list