Decoding the ID Token Yahoo sign in - yahoo

I hope someone can help, I am trying to get user data(name,email,etc) from yahoo sign in and I did exactly what doc say Oauth2 Yahoo
everything is fine, but in the last step the docs say after ur post request (sending the correct data) you will get this fields
access_token
id_token
expires_in
token_type
refresh_token
xoauth_yahoo_guid
but my result is
object(stdClass)[293]
public 'access_token' => string'LqV8XJaYvV.otOTRWAqkUKOApYpYi9Ewc.TrISqHPBC5TYjbgNxTXutpDUpLQAhthqM6CSHBLw.zzGh88iN.OIg.yLebST6JZDuRmRgJJMpOEzhOAxDhQosKVmFayt8YDVXiQSlT23qXMvJrTNYa8rKcofyrkU3TGMUySkjEAuS2667kDJUsCVkYWGUi5nnK.ZyShLosS.sygv0.VCAvONAvZeUcfptHCp9sJ0XVnwwXrrKYLOIFQMogdZYFc8YHz7MjAHXsxK1y4DZR6aEbSj.1ZGUiSnV7MEJ73SQEan8xakFs7posnyQo1WZOcbOnYZ_TQvcPkT1QQs96xngbkW.QbFKU4BVnZ0qbkXTcdsK3GEXXJrrliNOdxIesBA5joWYQKCZcr4aq42lEdedERx9OYggPwlqM5Xy1Mr5N._rHIAnOS0tVG_TNUHvRIGuXaRp9DeIBz9PKLWqRYWjwF0zFnVaE9iRpufpn.ZzRkx7UZlWS6TlZEn7FjEOXu6CJ'...
public 'refresh_token' => string'AJbEoFk51gPXOEgzJPsMhCSbmK9VFFaGydxb925fxB4mi5Pfm98-'
public 'expires_in' => int 3600
public 'token_type' => string 'bearer'
public 'xoauth_yahoo_guid' => string 'E7HLX6HSEMQRFGE3HL3ANLH4HM'
how you can see i am not getting id_token any idea??

For getting user data use your xoauth_yahoo_guid and check this documentation of yahoo GUID.
No need to use id_token
Call the HTTP GET operation on the following URI:
http://social.yahooapis.com/progrss/v1/users.guid(E7HLX6HSEMQRFGE3HL3ANLH4HM)/profile?format=json&.imgssl=1
Or use YQL Web Service:
YQL Console

Related

Ruby Oauth2 Signet Return token with refresh token

I am accessing gmail api. I am using ruby to get the access token. However, I need to get a refresh token with the access token. I am using signet as suggested here.
https://readysteadycode.com/howto-access-the-gmail-api-with-ruby
The code looks like this
client = Signet::OAuth2::Client.new({
client_id: ENV.fetch('GOOGLE_API_CLIENT_ID'),
client_secret: ENV.fetch('GOOGLE_API_CLIENT_SECRET'),
token_credential_uri: 'https://accounts.google.com/o/oauth2/token',
redirect_uri: url_for(:action => :callback),
code: params[:code]
})
// this is undefined
refre_token = client.refresh_token
response = client.fetch_access_token!
access_token = response['access_token']
I tried adding additional parameters like this as suggested here
additional_parameters: {
"access_type" => "offline", # offline access
"include_granted_scopes" => "true", # incremental auth
}
to the client.new call but did not seem to have any effect.
How do I get the refresh token from Signet::OAuth2?
The refresh token will only appear the first time you are authenticated.
Follow these steps to remove the stored access so you can be authenticated like the first time.
Manage your google account -> Security -> Manage 3rd party access -> your app name -> remove access
Note: From my testing, it does not appear that the additional parameters property is necessary.

Sales force refresh token could not generating in Laravel php

hope you all are doing well. I am stuck with an issue since couple of hours and could not be able to resolve it. Please have a look on error
enter image description here
I am trying to generate refresh token. Access_token generated successfully that is expired after 20 minutes. refresh token could not be generated
$client = new Client();
$res = $client
->request("POST",
"https://test.salesforce.com/services/oauth2/token",[
'body'=> json_encode([
'grant_type'=>'refresh_token',
'client_id'=>Config::get('forrest.info.client_id'),
'client_secret'=>Config::get('forrest.info.client_secret'),
'Authorization'=>'Bearer 00D3H0000008olE!ARYAQOzGGJDDIaygn7GokNk4T319XlDwwBXIDYPkJfej74dfhFT3CMDvBD2pZBQK_x.v2amiRe5Y29ZNXMp9EOA6ZTYyqrTW',
'access_token'=>'00D3H0000008olE!ARYAQOzGGJDDIaygn7GokNk4T319XlDwwBXIDYPkJfej74dfhFT3CMDvBD2pZBQK_x.v2amiRe5Y29ZNXMp9EOA6ZTYyqrTW',
])
]
);
dd ($res->getStatusCode());
any help or comment would be highly appreciated! thank for your time.
It seems like this error is returned from SalesForce API.
Looking at their documentation, it seems that they expect to see application/x-www-form-urlencoded not json.
Try out this code:
$client = new Client();
$response = $client->request('POST', '/post', [
'form_params' => [
'grant_type' => 'refresh_token',
'client_id' => Config::get('forrest.info.client_id'),
'client_secret' => Config::get('forrest.info.client_secret'),
'Authorization' => 'Bearer 00D3H0000008olE!ARYAQOzGGJDDIaygn7GokNk4T319XlDwwBXIDYPkJfej74dfhFT3CMDvBD2pZBQK_x.v2amiRe5Y29ZNXMp9EOA6ZTYyqrTW',
'access_token' => '00D3H0000008olE!ARYAQOzGGJDDIaygn7GokNk4T319XlDwwBXIDYPkJfej74dfhFT3CMDvBD2pZBQK_x.v2amiRe5Y29ZNXMp9EOA6ZTYyqrTW',
],
]);
dd($response);
let me know if it helped.
(Not an answer but too long for a comment)
This looks weird. "Authorization Bearer" should be a http header, not part of the message's body. Are you able to do what you need in plain old Postman, SoapUI etc?
Which OAuth2 flow did you use to generate this access token? Not all flows generate refresh token, for example https://help.salesforce.com/s/articleView?id=sf.remoteaccess_oauth_username_password_flow.htm&type=5 says "this flow doesn't support scopes" so you get full access - but also "this response doesn’t send a refresh token."
Have you checked the connected app (place in SF where you took client id and secret from), do the OAuth2 scopes include refresh? Did you ask for refresh token (included it in the original request's grants)?

Amazon Selling Partner API - signed request (ruby implementation)

Following the Amazon Selling Partner API Doc, I was able to get the LWA access token.
However, I'm getting blocked in making request to the REST API.
https://github.com/amzn/selling-partner-api-docs/blob/main/guides/developer-guide/SellingPartnerApiDeveloperGuide.md#connecting-to-the-selling-partner-api
I tried to use aws-sdk-signer to create a signed request
access_token = 'LWA access token'
signer = Aws::Sigv4::Signer.new(
access_key_id: 'my access id',
region: 'us-east-1',
secret_access_key: 'my access key,
service: 'execute-api',
)
signature = signer.sign_request(
http_method: 'GET',
url: 'https://sellingpartnerapi-na.amazon.com/orders/v0/orders',
headers: {
'host' => 'sellingpartnerapi-na.amazon.com',
'user_agent' => 'test (Language=Ruby)',
'x-amz-access-token' => access_token
})
response = HTTParty.send(:get, 'https://sellingpartnerapi-na.amazon.com/orders/v0/orders', headers: {
'host' => signature.headers['host'],
'user_agent' => 'test (Language=Ruby)',
'x-amz-access-token' => access_token,
'x-amz-content-sha256' => signature.headers['x-amz-content-sha256'],
'x-amz-date' => signature.headers['x-amz-date'],
'Authorization' => signature.headers['authorization'],
})
resposne
{"errors"=>[{"message"=>"Access to requested resource is denied.", "code"=>"Unauthorized", "details"=>"Access token is missing in the request header."}]}
It looks like I'm not signing the LWA access token correctly, but I have no idea what's going on since this is a new API and there's not much implementation especially in ruby.
Would anyone give some directions?
Update: I followed the Singer document
https://docs.aws.amazon.com/sdk-for-ruby/v3/api/Aws/Sigv4/Signer.html
Aws::Sigv4::Signer
For anyone stumbling across this:
Your problem likely stems from HTTParty (or other HTTP client gems) using Ruby's Net::HTTPHeader behind the scenes.
Net::HTTPHeader capitalizes all request headers before the request is sent and the x-amz-access-token header is case-sensitive.
If you're populating x-amz-access-token with a valid value and still receiving the following error:
{
"message": "Access to requested resource is denied.",
"code": "Unauthorized",
"details": "Access token is missing in the request header."
}
...then you're likely running into this issue.
You can bypass this by overloading Net:HTTPHeader.capitalize like so:
module Net::HTTPHeader
def capitalize(name)
name
end
private :capitalize
end
see also: https://github.com/amzn/selling-partner-api-docs/issues/292#issuecomment-759904882
"Access token is missing in the request header" sounds like something is wrong with your x-amz-access-token. Are you retrieving it like this? https://github.com/ericcj/amz_sp_api/blob/main/lib/sp_api_client.rb#L40

How to construct a private sever-to-client-side API? Laravel Passport?

I'm not sure if I'm using the correct method for my problem.
I would like to get Infos via Axios. For example: calling: /api/user with Axios gets me the user, but I don't want to see the information when I go on domain.test/api/user.
I even want to use API calls to get Results of Functions even if the User is a Guest.
I installed everything there is on the Laravel Documentation for API, but still I'm not sure how the user gets the Token.
So if I call:
axios.get('/api/user')
.then(response => {
console.log(response.data);
});
I get from the network tab {"message":"Unauthenticated."}. (I didn't forget to set: ...Middleware\CreateFreshApiToken::class and everything there is).
I think my problem is that I didn't register the User correctly. I got my two keys what should I do with it?
And then it's weird, reading the blog https://laravelcode.com/post/laravel-passport-create-rest-api-with-authentication, they use
$success['token'] = $user->createToken('MyApp')->accessToken;
But I don't get it. Where do I save it? I'm super confused, because every blog about shows Laravel Passport completely differently.
Or am I doing it wrong?
Passport is an OAuth2 server implementation which offers several different authorization strategies. While it is certainly possible to use Passport for authentication, it's primary purpose is authorization. This is done via token scopes. The type of token you choose to issue depends on your intended purpose with the API and whom your intended target is to be consuming your api.
Let's start with the following:
$success['token'] = $user->createToken('MyApp')->accessToken;
Here they are creating Personal Access Tokens. This is the simplest means of consuming your api, since clients are able to create the token themselves as needed and are long lived.
The Password Grant strategy is also a good option. A common approach when using this strategy is proxying authentications to Passport internally and merging the client id and secret into the request in a middleware.
public function handle($request, $next) {
return $next(tap($request, function($request) {
$request->merge([
'client_id' => config('services.passport.client.id'),
'client_secret' => config('services.passport.client.secret')
]);
// do any other pre-request work needed here
}));
}
Setup
To get started with Passport, run the command:
php artisan passport:install
This will create the encryption keys as well as a personal access and password grant client types, which will be stored in your database in the oauth_clients table.
Guard and Middleware
API routes need to be using the api guard, done by setting auth:api middleware on the route group(s) or Controller constructor.
// using via constructor
public function __construct()
{
$this->middleware('auth:api');
}
// via a route group
Route::group(['middleware' => ['auth:api'], function() {
// your api routes
});
Passport Routes
Your user model needs to be using the trait HasApiTokens and within the AuthServiceProvider call Passport::routes() in the boot method.
public function boot()
{
$this->registerPolicies();
Passport::routes();
// this is also an ideal time to set some token expiration values
Passport::tokensExpireIn(now()->addDays(15));
Passport::refreshTokensExpireIn(now()->addDays(30));
}
To use the personal access token strategy for authentication, you need to create your own login and logout routes instead of using the builtin Laravel auth mechanisms.
Referring to the tutorial in your question, they have defined the following routes:
Route::post('login', 'API\PassportController#login');
Route::post('register', 'API\PassportController#register');
and the login method implemented as:
public function login(){
if(Auth::attempt(['email' => request('email'), 'password' => request('password')])){
$user = Auth::user();
$success['token'] = $user->createToken('MyApp')->accessToken;
return response()->json(['success' => $success], $this->successStatus);
}
else{
return response()->json(['error'=>'Unauthorised'], 401);
}
}
This is expecting a ajax request with an email and password to be posted to login and if successful it responds with an access token.
Storing/Using the Token
This token must be stored client side, either in a cookie or local storage, for example, and then added to every request from the client there after. You'll add the token to the Authorization header in client requests.
// Use a response interceptor to check for a token and put it in storage
axios.interceptors.response.use(response => {
// store the token client side (cookie, localStorage, etc)
if (response.data.token) {
localStorage.setItem('token', token)
}
return response
}, error => {
// Do something with response error
return Promise.reject(error);
});
// Use a request interceptor to add the Authorization header
axios.interceptors.request.use(config => {
// Get the token from storage (cookie, localStorage, etc.)
token = localStorage.getItem('token')
config.headers.common['Authorization'] = `Bearer ${token}`
return config;
}, error => {
// Do something with request error
return Promise.reject(error);
});
Accessing the Authenticated User
In order to get the user, pass the 'api' parameter to the auth() helper, Auth facade, or through the request:
$user = auth('api')->user();
$user = Auth::user('api');
$user = request()->user('api');
Keep in mind personal access tokens are long lived, so it's up to you to decide when and how they should expire.
Any http client can be used to make api requests, axios is a very common option and included with each Laravel installation.

mailchimp 3.0 authentication fails

Authentication fails for the following, which gets posted to mailchimp using CURL, where API_KEY is defined as a string containing my key. Similar code used to work just fine for mailchimp v2:
$params = array ('apikey' => API_KEY,
'email_address' => $email,
'status' => 'pending',
'merge_fields' => array ('fname' => $first_name,
'lname' => $last_name
)
);
The error is:
{"type":"http://kb.mailchimp.com/api/error-docs/401-api-key-missing",
"title":"API Key Missing",
"status":401,"detail":
"Your request did not include an API key.",
"instance":"(long number)"
}
That's not how authentication works in v3.0. From the documentation:
The easiest way to authenticate is using HTTP Basic Auth. Enter any string as the username and supply your API Key as the password. Your HTTP client library should have built-in support for basic authorization.
If you're using PHP, every HTTP library knows how to do this. I'd recommend Guzzle or PHP Requests, but even basic cURL in PHP can do basic auth easily.
The interests syntax looks okay, except that the value should be a boolean instead of a string.

Resources