How do I get an access token using a refresh token? - oauth-2.0

First, if this question is badly formed, I apologize.
In simple terms, the API server documentation that I'm trying to connect to provides this guidance:
Authentication Workflow The authentication workflow comprises of two steps:
Use your refresh token to get a client-scoped access token
Use the client-scoped access token to access resources
I'm stuck at step one.
I am using Guzzle 6.x and trying to authenticate via OAuth2.
Using Postman, I able to obtain the access token easily. I'd like to do this in my code using Guzzle. (or whatever it takes).
Postman generated the following PHP HttpRequest snippet. Can I do that with Guzzle? (does the question even make sense?)
<?php
$request = new HttpRequest();
$request->setUrl('https://api-tra/v3/partners/oauth2/token');
$request->setMethod(HTTP_METH_POST);
$request->setHeaders(array(
'cache-control' => 'no-cache',
'Connection' => 'keep-alive',
'Content-Length' => '559',
'Accept-Encoding' => 'gzip, deflate',
'Content-Type' => 'multipart/form-data; boundary=--------------------------158986490184667130446156',
'Host' => 'api-train.daxko.com',
'Postman-Token' => '28b9d8ac-d0ae-4036-9a61-202e9b39b220,f89cb196-9ada-4c1a-92f7-afc322fec03b',
'Cache-Control' => 'no-cache',
'Accept' => '*/*',
'User-Agent' => 'PostmanRuntime/7.19.0',
'Authorization' => 'Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3yYWluLWF1dGgiLCJzdWIiOiJmbWN3ZWJzaXRlX3RyYWluIiwiaWF0IjoxNTcwNTQ4OTE3LCJleHAiOjE1NzA1NDg5MTcsImFwaSI6Im9wc19hcGlfdjJfYXV0aCJ9.EnbGN121Ei5hlkPFT6Iqyd1h9_WXDGKplu5RsCH5QZs',
'content-type' => 'multipart/form-data; boundary=----WebKitFormBoundary7MA4YWxkTrZu0gW'
));
$request->setBody('------WebKitFormBoundary7MA4YWxkTrZu0gW
Content-Disposition: form-data; name="grant_type"
client_credentials
------WebKitFormBoundary7MA4YWxkTrZu0gW
Content-Disposition: form-data; name="client_id"
fmcwebsite_train
------WebKitFormBoundary7MA4YWxkTrZu0gW
Content-Disposition: form-data; name="client_secret"
blC}g!!E#{+_k.VLH
------WebKitFormBoundary7MA4YWxkTrZu0gW
Content-Disposition: form-data; name="scope"
client:2069
------WebKitFormBoundary7MA4YWxkTrZu0gW--');
try {
$response = $request->send();
echo $response->getBody();
} catch (HttpException $ex) {
echo $ex;
}

You are using client credentials and in that flow refresh tokens are not typically used. Instead just send the access token to the API. If you use the token for long you may also need to check for a 401 response status when you call the API. If so then re-authenticate and call the API again with a new access token.

Related

Service now oauth grant flow error with oauth_token.do

I follow the article OAuth authorization code grant flow to get tokens
Initially I made request:
dev234.service-now.com/oauth_auth.do?response_type=code&client_id=****534e4e81b7f
and the response after allowing access to:
http://callback-url?code=Z2YYGhgfh1tMoFPDO7Dr0nZuPnhQPs53qwkm_Sw99gpUf92gU3x_OOuoOqdYBvlPFF01pOfgZg9VoXpCruSRYQ
after that to get token:
dev234.service-now.com/oauth_token.do?grant_type=authorization_code&code=<***>&client_id=<***>&client_secret=<***>
When I did request this, throwing error
{"error_description": "access_denied","error": "server_error"}
Can't I get access_token and refresh_token in json format?
At last worked,
after getting code from earlier steps,i made a php request looks like::
$client = new Client();
$post_data = [
'grant_type' => 'authorization_code',
'code' => 'your code',
'redirect_uri' => '<callback_url>',
'scope' => 'useraccount'
];
$auth = base64_encode('<client_id>:<client_secret>');
$res = $client->request('POST', 'https://myinstance.service-now.com/oauth_token.do', [
'headers' => [
'Authorization' => 'Basic ' . $auth,
'Content-Type' => 'application/x-www-form-urlencoded'
],
'form_params' => $post_data
]);
dd(json_decode($res->getBody(), true));
The response contains accesstoken and refresh token.
Check step two
https://myinstance.servicenow.com/oauth_auth.do?grant_type=code&code={the auth code}&redirect_uri={the_same_redirect_url}&client_id={the_same_client_identifier}
you are using
grant_type=authorization_code

Spotify Web API Bad Request Error "invalid_client" when refreshing token

I'm building an app in Rails using the Spotify web API. I built a method to refresh a user's token, but am receiving a 400 error. According the the Spotify Web API docs, the header of my request needs to be in the following format:
Authorization: Basic <base64 encoded client_id:client_secret>
Using Httparty gem, here's the POST method to refresh the access token:
def refresh_token
client_id = "foo"
client_secret = "bar"
client_id_and_secret = Base64.encode64("#{client_id}:#{client_secret}")
result = HTTParty.post(
"https://accounts.spotify.com/api/token",
:body => {:grant_type => "refresh_token",
:refresh_token => "#{self.oauth_refresh_token}"},
:headers => {"Authorization" => "Basic #{client_id_and_secret}"}
)
end
Here's what "result" ends up being:
=> #<HTTParty::Response:0x7f92190b2978 parsed_response={"error"=>"invalid_client", "error_description"=>"Invalid client secret"}, #response=#<Net::HTTPBadRequest 400 Bad Request readbody=true>, #headers={"server"=>["nginx"], "date"=>["Sun, 31 Aug 2014 22:28:38 GMT"], "content-type"=>["application/json"], "content-length"=>["70"], "connection"=>["close"]}>
I can decode client_id_and_secret and it returns "foo:bar", so I'm at a loss as to why I'm receiving a 400 error. Any insight is much appreciated.
Found the issue... it was with the Base64 encoding in Ruby. Apparently (as shown in Strange \n in base64 encoded string in Ruby) using the Base64.encode64('') method adds an extra line within the code. Using Base64.strict_encode64('') solved the issue.
Updated code:
def refresh_token
client_id = "foo"
client_secret = "bar"
client_id_and_secret = Base64.strict_encode64("#{client_id}:#{client_secret}")
result = HTTParty.post(
"https://accounts.spotify.com/api/token",
:body => {:grant_type => "refresh_token",
:refresh_token => "#{self.oauth_refresh_token}"},
:headers => {"Authorization" => "Basic #{client_id_and_secret}"}
)
end

Rails RestClient pass token in header fails

I do this curl in Terminal which works excellent:
$ curl https://myurl.com/api/v1/orders/53e0ae7f6630361c46060000 -H "Authorization: Token xxxxxxxxxxxxxxxxxxxxxx"
Output is json.
Now I want to access the json string via my rails app. I have tried RestClient to do this, but somehow I always get a 401 unauthorized error. I believe the token gets not send correctly via header. I have tried the following:
RestClient.get 'https://myurl.com/api/v1/orders/53e0ae7f6630361c46060000', {token: 'xxxxxxxxxxxxxxxxxxxxxx'}
and
RestClient.get 'https://myurl.com/api/v1/orders/53e0ae7f6630361c46060000', :params => {:token => 'xxxxxxxxxxxxxxxxxxxxxx'}
with no success. Maybe I use a wrong syntax for sending the token in the header?
Doku is here http://rubydoc.info/github/rest-client/rest-client - I could not find any mistakes.
# GET request with modified headers
RestClient.get 'http://example.com/resource', {:Authorization => 'Bearer cT0febFoD5lxAlNAXHo6g'}
# POST request with modified headers
RestClient.post 'http://example.com/resource', {:foo => 'bar', :baz => 'qux'}, {:Authorization => 'Bearer cT0febFoD5lxAlNAXHo6g'}
# DELETE request with modified headers
RestClient.delete 'http://example.com/resource', {:Authorization => 'Bearer cT0febFoD5lxAlNAXHo6g'}
Source: https://github.com/rest-client/rest-client#headers

Make Http Post request with new password rest-client

I'm trying to change a password over a rest interface with rest-client.
With the instructions shown below a basic authentication is required.
I think I implemented the basic authentication right in my request. My problem is that I don't know how I should set a new Password in the requestBody
The instructions, example:
URL: {base_url}/accounts/{uid}/password
HTTP-Method: POST
Request Body: text/plain
Response Body: text/plain
HTTP Status Code: 201, 400
Entitlement: Owner
Request:
POST /accounts/345/password HTTP/1.1
Content-Type: text/plain;charset=UTF-8
newPassword
Response:
Status Code: 201 Created
My code:
#response = RestClient::Request.new(
:method => :post,
:url => 'https://zomgo.de:7849/server/rest/accounts/50s89c-a76b-475/password',
:user => 'hrums80',
:password => 'mzsdfr4',
:newPassword => 'Amerika69'
).execute
With this code I get the following error:
Http 415 unsopported media type
Can someone say me how I can set a new password in the request body ? And what's the meaning of that error. Thanks

Failed to open stream: HTTP request failed! HTTP/1.0 400 Bad Request - OAuth 2.0 POST

I am working with YouTube APIs for my college project, and I keep getting an error. Here I send them to the authorisation page to log in, when they allow access it sends the $_GET['code'] string back. Then I send this along with some other data and it should send back a JSON object. Instead I am just getting
Warning: file_get_contents(https://accounts.google.com/o/oauth2/token)
[function.file-get-contents]: failed to open stream: HTTP request
failed! HTTP/1.0 400 Bad Request in http://www.example.net/callback.php on line 27
I have replaced my domain with example.net just for security
urlencode($_GET['code']),
'client_id' => urlencode('111522767640.apps.googleusercontent.com '),
'client_secret' => urlencode('secret'),
'redirect_uri' => urlencode('http://example.net/callback.php'),
'grant_type' => urlencode('authorization_code')
)
);
$params =
array('http' =>
array(
'method' => 'POST /o/oauth2/token HTTP/1.1',
'header' => 'Host: accounts.google.com\r\n'.
'Content-Type: application/x-www-form-urlencoded',
'content' => $postdata
)
);
$context = stream_context_create($params);
$result = file_get_contents('https://accounts.google.com/o/oauth2/token', false,$context);
var_dump($_SESSION);
var_dump($result);
}
else //If code isnt set, user must have come here erroniously or has denied access to this program
{
//header( 'Location: www.example.net/error.php' ) ;
}
?>
file_get_contents is going to make a GET request to the url specified, but oauth2/token needs a POST request.
See reference Google OAuth2, PHP HTTP.
if you are using oauth2, goto libraries/oauth2/provider.php and uncomment the code line 182 shows
$ci = get_instance();
$ci->load->spark('curl/1.2.1');
$ci->curl
->create($url)
->post($params, array('failonerror' => false));
$response = $ci->curl->execute();
Here's how to do the Google oAuth properly:
$config = (object) array(
'CLIENT_ID' => 'AAAAA',
'CLIENT_SECRET' => 'BBBBB',
'REFRESH_TOKEN' => 'CCCCC',
);
$sJSON = file_get_contents('https://www.googleapis.com/oauth2/v4/token',FALSE,
stream_context_create(array('http'=>array(
'ignore_errors' => TRUE, // see errors in response instead of empty on error
'method' => 'POST',
'header' => array(
'Content-Type: application/x-www-form-urlencoded'
),
'content' => http_build_query(array(
'grant_type' => 'refresh_token',
'client_id' => $config->CLIENT_ID,
'client_secret' => $config->CLIENT_SECRET,
'refresh_token' => $config->REFRESH_TOKEN
))
)))
);
You can then use json_decode() to parse $sJSON into an object and then retrieve the access_token property.
For those who are wondering how to get the CLIENT_ID, CLIENT_SECRET, and REFRESH_TOKEN, watch this video. It's not easy. In my case, I needed to do this for Google Adwords API. So, I had to get my Developer Token and Login Customer ID from https://ads.google.com/home/tools/manager-accounts. Then, I had to go to https://console.developers.google.com/apis/credentials with this guide to generate a Client ID and Client Secret. Then, I followed this guide to learn how to get my Refresh Token.

Resources