Current method to get new access token from refresh token - google-api-nodejs-client

I see some questions about this with solutions that seem to be deprecated in the Google APIs Node.js Client OAuth API (e.g., this and this).
There's no documentation I can see regarding using the refresh token to get a new access token (docs section). In an issue from early 2017, someone mentions getting off the oauth2Client.credentials property, but it looks like that's within a call to one of the other APIs wrapped in the package.
In my use case, I'm querying the Google My Business (GMB) API, which is not wrapped in there, but I'm using the OAuth piece of this package to authenticate and get my tokens.
My request to the GMB API (using the request-promise module), looks something like this:
function getLocations () {
return request({
method: 'POST',
uri: `${gmbApiRoot}/accounts/${acct}/locations:batchGet`,
headers: {
Authorization: `OAuth ${gmbAccessToken}`
}
})
.then(function (response) {
console.log(response);
})
.catch(function (err) {
// ...
});
}
I don't think I can pass the oauth2Client into the headers for authorization like in the issue response. Is there a way to directly request a new access_token given that I have my refresh token cached in my app?
Update: Solved! Thanks to Justin for the help. Here's what my working code is looking like:
oauth2Client.setCredentials({
refresh_token: storedRefreshToken
});
return oauth2Client.refreshAccessToken()
.then(function (res) {
if (!res.tokens && !res.credentials) {
throw Error('No access token returned.');
}
const tokens = res.tokens || res.credentials;
// Runs my project-level function to store the tokens.
return setTokens(tokens);
});

If you have an existing oauth2 client, all you need to do is call setCredentials:
oauth2client.setCredentials({
refresh_token: 'REFRESH_TOKEN_YALL'
});
On the next call that goes through the client, it will automatically detect there is no access token, notice the refresh token, and go snag a new access token along with it's expiration date. I outlined some docs and code around this in the issue you opened up on GitHub :P
https://github.com/google/google-api-nodejs-client/pull/1160/files
Hope this helps!

I wanted to add in my learning, to the community, in case it helps anyone out there struggling with this too. The above answers were correct, but I discovered one other attribute.
Namely, I was calling my credentials like this:
oAuth2Client.setCredentials(JSON.parse(authResults));
my authResults, is defined as this:
const authResults = fs.readFileSync(TOKEN_PATH);
This results in several fields being filled in to the results variable:
[
'access_token',
'refresh_token',
'scope',
'token_type',
'expiry_date'
]
Now here's the nuance...if the access_token AND the refresh_token are both given to the setCredentials call, the refresh-token is ignored. Changing to the above answer, where I send in only the refresh token:
oAuth2Client.setCredentials({ refresh_token: creds['refresh_token'] });
Worked like a champ! Hope this finds its way and helps someone else.

Related

How to use Laravel Passport access tokens

First let me describe the problem I want to solve. I have a Laravel backend project that I want to tranform into an API, and it looked like Laravel Passport was perfect for this. Therefore, I installed Laravel Passport into my project.
I have a client app which needs to use this API using axios. What I want to do is to make a post request with my username and password to the API to get an access token, and then use this access token to get or post relevant data. The access token is created by the following code
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['token']);
// return response()->json(['success' => $success], 200);
} else {
return response()->json(['error' => 'Unauthorised'], 401);
}
}
and my app stores the access token. Am I correct in thinking that my app can now use this access token to gain access to the data of the user I made the login with? If so, how would I do that? I have tried using this, but I could not make it work.
I will gladly post more code if needed!
Maybe this could help. when i store the access token on my frontend app i also attach the header
axios.defaults.headers.common['Authorization'] = "Bearer " + token.data.access_token
all your axios request will use this header.
getting user detail
Route::middleware('auth:api')->get('/user', function (Request $request) {
return $request->user();
});

Meteor: Implement facebook package outside of accounts-facebook

I've got a Meteor application with a multi-phase sign-up process. The accounts are based on the accounts-password package. In the step prior to account creation, the user needs to provide some profile information.
I'd like the user to be able to launch a Facebook OAuth flow which pre-populates the profile fields with information pulled from Facebook.
This all needs to happen pre-account-creation. I want to implement this with the facebook package that backs accounts-facebook.
At the moment I've got the OAuth flow happening by calling Facebook.requestCredential, but I'm not sure how to get an OAuth access token from the credential token that comes back. I suspect I need to pass this to the server and make an API call to get back an access token.
Any pointers as to how this should work would be much appreciated.
Facebook.requestCredential(function (credentialTokenOrError) {
if (credentialTokenOrError && credentialTokenOrError instanceof Error) {
// Error...
console.log(credentialTokenOrError);
} else {
// Credential Token string
console.log(credentialTokenOrError);
// Now perhaps a Meteor.call to a server method that
// 1. Retrieves an access token
// 2. Hits the graph API to get profile information and returns it to the client
}
});
Thanks,
Chris
I was having the same trouble of converting a credentialToken to an accessToken, only with Github. I've written up a gist that has code that should work very similarly. Essentially, there are two steps:
Within your Facebook.requestCredential callback function, call OAuth._retrieveCredentialSecret(tokenOrError), the result of which is the credentialSecret. Then use Meteor.call, passing in tokenOrError and credentialSecret, to call the Meteor.method you'll set up in the next step.
code (on client):
Github.requestCredential({
loginStyle: 'popup',
requestPermissions: ['gist']
}, function(tokenOrError) {
if (tokenOrError && tokenOrError instanceof Error) {
// Throw a Meteor error
console.log('error getting the token');
return;
}
var credentialSecret = OAuth._retrieveCredentialSecret(tokenOrError);
Meteor.call('getGithubAccessToken', tokenOrError, credentialSecret, function(err, accessToken) {});
});
On the server, set up a Meteor.method that takes your credentialToken and credentialSecret and calls Facebook.retrieveCredential. This function returns a credentials object from the _pendingCredentials Mongo Collection before deleting it from the collection. The access token is credentials.serviceData.accessToken. The credentials object could potentially be persisted in the user object in the Meteor.users collection (as it is in the accounts packages) or sent back to the user.
code (on server):
Meteor.methods({
getGithubAccessToken: function(credentialToken, credentialSecret) {
var credentials = Github.retrieveCredential(credentialToken, credentialSecret);
console.log('accessToken:', credentials.serviceData.accessToken);
return credentials.serviceData.accessToken;
}
});
I'm unfamiliar with the specifics of Facebook's Graph API so after these steps, you're on your own. Good luck!

Should I pass access token when using FB.api()?

I'm just a little confused as to how to pass my access token into FB.api() when making requests for protected things.
I'm getting my app to login and authenticate fine, but how do I use FB.api() with the access token I have?
app.accessToken = response.authResponse.accessToken; // This is a valid access token.
FB.api('/me/friends?access_token='+app.accessToken, {fields: 'name,id,location,picture,installed'}, function(response) {
console.log(response);
});
Is that the correct way to pass in the access token to FB.api()?
In this case, my response comes back with the friends name,id,location,picture but it doesn't seem to have the 'installed' data as that is protected.
Am I doing this right?
Although I see why some users are saying you may not need to pass access token due to your specific use.
Generally, there are cases where you do need to pass an access token through FB.api()
The way this is done is by passing it in the parameter object, as such:
FB.api('/{fb-graph-node-goes-here}/, {
access_token: "TOKEN GOES HERE"
//other parameters can go here aswell
}, function(response) {
console.log(response);
});
You do not need to pass the token, if the user logged in (with FB.login, for example). In fact, by using the JavaScript SDK (or PHP SDK), you almost never need to deal with the (user) access tokens.
So, your call would just be like this:
FB.api('/me/friends', function(response) {
console.log(response);
});
Getting the info if the user installed the app:
Test if user has application installed with Graph API
How to fetch a list of the current users' friends who also use my app?
That is how I did it:
Pass access_token as a parameter.
FB.api("/me", { access_token : response.authResponse.accessToken }, {fields: ['last_name', 'first_name', 'name']},
function (response) {
console.log(response);
console.log('Name: ' + response.name);
}
);
You would need to pass access token if requesting for extending fields. Please refer to
https://developers.facebook.com/docs/facebook-login/permissions/v2.0#reference-extended-profile

Different Facebook access token JavaScript SDK

I'm quite confused with the access token from facebook..here is how I obtain the user's access token and use it to get data from graph API
window.fbAsyncInit = function() {
FB.init({
appId : 'app ID',
status : true,
cookie : true,
xfbml : true,
oauth : true,
});
FB.getLoginStatus(getStatus);
FB.Event.subscribe('auth.authResponseChange', getStatus);
function getStatus(response) {
if ( response.status === 'connected' ) {
var accessToken = response.authResponse.accessToken;
console.log("accessToken = " + accessToken);
$.ajax({
dataType : "jsonp",
type : "GET",
url : "https://graph.facebook.com/me/albums?access_token=" + accessToken,
success : function(data) {
$.each(data, function(index, value) {
console.log(index + ": " + value);
})
}
});
}
}
};
However, I always get an empty data. After I visit the graph API documentation here: https://developers.facebook.com/docs/reference/api/ and click on one of the graph links, I notice that the access token generated there is always different from what I retrieve from my code. For example, the current access token in the graph api documentation is
"AAAAAAITEghMBAMwuyHZCO3VOAvCm9hHpaZC9PGV9238ixsZB7zSfuplZBTZCLRj6cEViZADJlVcjOfInwvcbhqu3XBF1w4ZAxvPbexcGQZAYzb4bHAKsMbLF"
and the one in console log is
"AAAG0ZCFantJ8BAAFcMdDOyDyT4OBtjrvULEaS2o94gZAU7U1xITaogFXCZBghQP8G9bjEh3XSCATQOZCUSZCuNWFvEfypIAmcz9bkbk5qRBlHUZAOE4guW"
I think that I may have done this the wrong way. Can anyone help explain to me how to retrieve data from graph API in a correct way?
Any kinds of help will be appreciated. Thanks in advance :)
Run this URL with your authToken first:
https://graph.facebook.com/me/permissions?access_token=USER_ACCESS_TOKEN
You'll almost certainly only see basic permissions in the response, which is why you aren't getting the data from your call to the user's album.
You'll then want to run your user through the Authentication Process, making sure you request the permissions you need (probably 'user_photos' in your case).
More info is available in those two links. Good luck!
access token will never be the same. So that behaviour is correct.
Back to your problem , I think its mostly scope related issue.
I had developed a application using facebook c# sdk, In that application i did it like this:
when a post is to be submitted , redirect the user to facebook (with some parameters like appid, app-secret, auth-token and
redirect-url);
Facebook will ask the user to login with his credentials.
When the user is logged in, facebook will redirect back to the redirect-url. (with the authtoken and a new auth-code).
Then we should use this auth-code, app-id and app-secret and obtain the user-access-token. (This is done by doing a rest api call to the
url
https://graph.facebook.com/oauth/access_token?client_id=client_id&redirect_uri=redirect_uri&client_secret=client_secret&code=auth-code
This will return the user-token and expiry time for the token
And then we can post using this user-access-token to the fb.
Initially i had misunderstood the auth-code and used it as the user-access-token, and i always got the result as unauthorised token .
Please check whether this will help you or not.

How to retrieve the facebook oauth 2.0 access_token

I am trying to get the access_token of the logged in facebook user.
I get something like this.. url followed by the code i am retrieve the code..
it says in the guide to exchange it for access_token...
https://graph.facebook.com/oauth/access_token?
client_id=XXXXXXXXXXXXXX&
redirect_uri=http://www.my-site.com/&
client_secret=XXXXXXXXXXXXXXXXXXXXX&
code=2.hJFWoMlLf3tLOSos_qNCBg__.3600.1279836000-10000100XXXXXXX|kGwPB4y5K_-ijD9_1CfjSpT-oaY..
How i can exchange it for a access_token using what FB.api or jquery or javascript..
When i plug this url in the address bar.. i am able to see access_token..
I appreciate if somebody can tell me how to retrieve the access_token using javascript or jquery.
Thanks.
According to Facebook, and my personal experiences with the api, the FB.getSession() function is deprecated and should throw an exception if called.
From facebook:
The FB.getAuthResponse method is a replacement for the FB.getSession method which was deprecated after the migration to OAuth 2.0.
Instead you should use the getLoginStatus callback -
FB.getLoginStatus(function(response) {
var token = response.authResponse.accessToken;
});
//Example structure of response object
var eg =
{
status: 'connected',
authResponse: {
accessToken: '...',
expiresIn:'...',
signedRequest:'...',
userID:'...'
}
};
source: http://developers.facebook.com/docs/reference/javascript/FB.getLoginStatus/
If you are using the JavaScript SDK, then after logging in the user, getting the access token in your JavaScript code is as simple as:
FB.getSession().access_token
However, getSession may return null if a user is logged out, so the proper way is to first check for null before accessing the token.
var session = FB.getSession();
if(session != null) { // user is still logged in
console.log(session.access_token);
}