I'm trying to get an unauthenticated token from Vimeo's current API v3, in order to use it to get a simple list of my own videos on my own website. I'm using a WordPress HTTP API function 'wp_remote_post' to generate a proper http request.
According to Vimeo, this is the correct way to do this and it's done with a POST request. Here are the arguments:
HTTP Method: POST
HTTP URL: api.vimeo.com/oauth/authorize/client
HTTP Headers: Authorization: basic, base64_encode( "$client_id: $client_secret" )
Request Body: grant_type=client_credentials&scope=public%20private
and getting
[body] => {"error":"You must provide a valid authenticated access token."}
[raw] => HTTP/1.1 401 Authorization Required
Why is Vimeo asking for a valid authenticated access token on an explicitly UNauthenticated call? I have provided the actual client id and client secret from my Vimeo app, using Vimeo's instructions to receive an unauthenticated access token. I'm sending the request from my local environment.
I have checked the similar question How to generate Vimeo unauthenticated access token? and have followed everything outlined there. No dice, and i've been trying to do this for hours.
Vimeo API seems to only accept the parameters as part of the query string, not as part of the HTTP POST object ('body', 'data', or other).
Only when I coded the parameters directly into the URL, rather than passing them as parameters in the post object, the post worked.
Works:
$url = 'https://api.vimeo.com/oauth/authorize/client?grant_type=client_credentials&scope=public%20private';
$auth = base64_encode( $developer_key . ':' . $secret_key );
$headers = array(
'Authorization' => 'Basic ' . $auth,
'Content-Type' => 'application/json'
);
$args = array(
'headers' => $headers
);
$response = wp_remote_post( $url, $args );
Does Not Work:
$url = 'https://api.vimeo.com/oauth/authorize/client';
$auth = base64_encode( $developer_key . ':' . $secret_key );
$data = array(
'grant_type' => 'client_credentials',
'scope' => 'public private'
);
$headers = array(
'Authorization' => 'Basic ' . $auth,
'Content-Type' => 'application/json'
);
$args = array(
'headers' => $headers,
'data' => $data
);
Hmmm. As of WordPress 4.6, the WP_HTTP class is now built on Requests by Ryan McCue.
So it seems my question is really also a question about how wp_remote_post() constructs the request. There does not seem to be a way to pass the parameters to the function and have them stringified in the URL.
Related
I try to get a list of messages from the currently logged in user. I am using Guzzle client to make a request. Unfortunately I don't quite understand the Google docs about the API.
This is what I have so far:
$client = new Client;
$headers = [
'content-type' => 'application/json',
'Authorization' => 'Bearer '.$token->access_token
];
$params = [
'maxResults' => 10,
'client_id' => config('gmail.clientId'),
'client_secret' => config('gmail.clientSecret'),
];
$response = $client->get('https://www.googleapis.com/gmail/v1/users/me/messages', [
$headers,
$params
]);
With this code I receive a message "Error 401 - Login Required". How can I achieve this? In my application every user is connected to their own Gmail account. The access_tokens are saved in a database.
I'm not sure about the Google API that you are using, but you definitely have a Guzzle-related mistake:
$response = $client->get('https://www.googleapis.com/gmail/v1/users/me/messages', [
'headers' => $headers,
'query' => $params,
]);
Also according to the docs, you don't need to supply client_id and client_secret upon every request. Take a look at Google's official auth lib for PHP, or/and at the complete SDK.
I have problem with my code, the error I get is:
Warning: fopen(https://discordapp.com/api/v6/auth/login): failed to open stream: HTTP request failed! HTTP/1.1 400 BAD REQUEST in
C:\xampp\htdocs\s2.php on line 15
Here is the relevant Code:
<?php
$data = array("email" => 'Email#gmail.com', "password" => 'Password');
$data_string = json_encode($data);
$context_options = array (
'https' => array (
'method' => 'POST',
'header'=> "Content-type: application/json\r\n"
. "Content-Length: " . strlen($data_string). "\r\n",
'content' => $data_string
)
);
$context = stream_context_create($context_options);
$fp = fopen('https://discordapp.com/api/v6/auth/login', 'r', false, $context);
?>
Thank you for your help!
It seems directly logging in via a bot is no longer allowed as you should use the OAuth2 (how does OAuth2 work?) functionality of Discord. This means that your bot needs to be set up inside your Discord account and then you may use token-based access on the bot to authenticate the external application against Discord.
The change to no longer allow bot-based logins happened around the beginning of 2017 and at that point all PHP-based Discord-related Github applications stopped to be maintained. Here is a discussion and comment about banning bots with automated login and this one about that OAuth2 has to be used.
Read more about authentication and bots in the Discord OAuth2 chapter.
If you can tell more about what you plan to achieve, maybe we can help you find a solution to your task.
Previous (no-longer working) answer:
I haven't used DiscordApp so I haven't tried this yet. Instead of sending JSON-encoded data, have you tried posting the values as FORM values to the API?
$postData = array(
'email' => 'Email#gmail.com',
'password' => 'Password'
);
$params = array('https' =>
array(
'method' => 'POST',
'header' => 'Content-type: application/x-www-form-urlencoded',
'content' => $postData
)
);
$context = stream_context_create($params);
// get the entire response ...
$result = file_get_contents('https://discordapp.com/api/v6/auth/login', false, $context);
// ... or alternatively using fopen()
$fp = fopen('https://discordapp.com/api/v6/auth/login', 'r', false, $context);
I haven't found any docs regarding how the parameters should be passed to the login URI but at least that's how normal form-based logins can be used.
According to the DiscordApp Response codes a 400 may be received if either the call was not understood (non-existent function called) or the parameters were send improperly so you should find out about how to call the logininterface with parameters using scripts.
I'm trying to test a Laravel API endpoint and want to call it in code.
$request = Request::create( $path, $method );
$response = Route::dispatch( $request );
This snippet works fine for GET but I need to be able to set up POST calls too. Setting the $method to POST works as well, but I can't find documentation detailing how to attach post data.
Any advice?
As you mentioned in the comments, you could use $this->call() but you can actually do it with your current code too. If you take a look at the signature of the Request::create() function you can see that it takes $parameters as third argument:
public static function create($uri, $method = 'GET', $parameters = array(), $cookies = array(), $files = array(), $server = array(), $content = null)
And the docblock says: The query (GET) or request (POST) parameters
So you can simply add the data to Request::create()
$data = array('foo' => 'bar');
$request = Request::create( $path, $method, $data );
$response = Route::dispatch( $request );
I've spent nearly a day trying to get this working myself for social authentication with passport and Angular front-end.
When I use the Restlet API Client to make the request I always get a successful response.
Restlet Client Request
Restlet client response
However using the following method of making internal requests always gave me an error.
$request = Request::create(
'/oauth/token',
'POST',
[
'grant_type' => 'social',
'client_id' => 'your_oauth_client_id',
'client_secret' => 'your_oauth_client_secret',
'provider' => 'social_auth_provider', // e.g facebook, google
'access_token' => 'access_token', // access token issued by specified provider
]
);
$response = Route::dispatch($request);
$content = json_decode($response->getContent(), true);
if (! $response->isSuccessful()) {
return response()->json($content, 401);
}
return response()->json([
'content' => $content,
'access_token' => $content['access_token'],
'refresh_token' => $content['refresh_token'],
'token_type' => $content['token_type'],
'expires_at' => Carbon::parse(
$content['expires_in']
)->toDateTimeString()
]);
This specific error:
{
error: "unsupported_grant_type",
error_description: "The authorization grant type is not supported by the
authorization server.",
hint: "Check that all required parameters have been provided",
message: "The authorization grant type is not supported by the authorization server."
}
I had the feeling it has to do with the way the form data is sent in the request, so while searching for a proper way to make such internal requests in laravel I came across this sample project with a working implementation: passport-social-grant-example.
In summary here's how to do it:
$proxy = Request::create(
'/oauth/token',
'POST',
[
'grant_type' => 'social',
'client_id' => 'your_oauth_client_id',
'client_secret' => 'your_oauth_client_secret',
'provider' => 'social_auth_provider', // e.g facebook, google
'access_token' => 'access_token', // access token issued by specified provider
]
);
return app()->handle($proxy);
Hope this helps.
I try to make google url shortener with wp_remote_post()
but I got error result,
I know how to use CURL, but CURL not allowed in WordPress!
This resource for API with WordPress:
http://codex.wordpress.org/Function_Reference/wp_remote_post
http://codex.wordpress.org/Function_Reference/wp_remote_retrieve_body
http://codex.wordpress.org/HTTP_API#Other_Arguments
http://codex.wordpress.org/Function_Reference/wp_remote_post#Related
This google url shortener API docs:
https://developers.google.com/url-shortener/v1/getting_started#shorten
This is my code:
function google_url_shrt{
$url = 'http://example-long-url.com/example-long-url'; // long url to short it
$args = array(
"headers" => array( "Content-type:application/json" ),
"body" => array( "longUrl" => $url )
);
$short = wp_remote_post("https://www.googleapis.com/urlshortener/v1/url", $args);
$retrieve = wp_remote_retrieve_body( $short );
$response = json_decode($retrieve, true);
echo '<pre>';
print_r($response);
echo '</pre>';
}
The WordPress API requires that the headers array contain an element content-type if you want to change the content type of a POST request.
Also, it looks like the body of your HTTP request is being passed as a PHP array, not as a JSON string as the Google Shortener API requires.
Wrap the array definition for body in a json_encode statement, and make the headers field a sub-array, and give it a shot:
$args = array(
'headers' => array('content-type' => 'application/json'),
'body' => json_encode(array('longUrl' => $url)),
);
Alternative, you could just write the JSON format yourself as it is fairly simple:
$args = array(
'headers' => array('content-type' => 'application/json'),
'body' => '{"longUrl":"' . $url . '"}',
);
Im trying to build an app that uses the simplenote api but I am having trouble with the authentication part. I am getting a 400 error(bad request).
Im guessing this issue is not related to the simplenote api, it's rather my understanding of the documentation.
Here is what the api is saying:
HTTP POST to the following URL:
https://simple-note.appspot.com/api/login
The body of the request should contain this, but base64-encoded:
email=[email-address]&password=[password]
To be clear, you will concatenate email= with the user’s email address (trimmed),
&password=, and the user’s password; then base64 the resulting string and send it as
the HTTP request body. (Do not encode this request using the standard variable
encoding used for POSTed web forms. We basically ignore the Content+Type header
for this request, but text/plain makes the most sense here.)
And here is my code so far:
$url = 'https://simple-note.appspot.com/api/login';
$data = array('email' => base64_encode($email), 'password' => base64_encode($password));
$options = array(
'http' => array(
'header' => "Content-type: application/x-www-form-urlencoded\r\n",
'method' => 'POST',
'content' => http_build_query($data),
),
);
$context = stream_context_create($options);
$result = file_get_contents($url, false, $context);
var_dump($result);
I think what they mean is:
$data = base64_encode(http_build_query(array(
"email" => $email,
"password" => $password
));
So base64 encode the resulting string, not the individual parts.
As for making the request. I can recommend you take a look at cURL, it's much faster than file_get_contents.