Google OAuth2 JS can't get Authorization Code - javascript

I have a custom Google Sign In button in React (follows branding guidelines) that I need to implement into a web app. The android app already has Google Sign In implemented with the BE and requires the authorization code to be sent to the BE. I seem to have trouble accessing the authorization code (I can get the access token, id, and id_token fairly easily though).
I initialize as such:
static googleInit (googleSignInID) {
gapi.load('auth2', () => {
ThirdPartyLogInApi.auth2 = gapi.auth2.init({
// Retrieve the singleton for the GoogleAuth library and set up the client.
client_id: `${googleSignInID}.apps.googleusercontent.com`,
})
})
}
In my React component, I attach a click handler to a React ref (as I've seen in other stackoverflow problems).
componentDidMount () {
// element, options, success, failure
ThirdPartyLogInApi.auth2.attachClickHandler(
this.button,
{},
this.onGoogleSuccess,
this.setProcessingToFalse
);
}
In the success callback (this.onGoogleSuccess), I am able to call googleUser.getBasicProfile() to get user information and googleUser.getAuthResponse(true) to get id_token and access_token, but I need the authorization code too.
I'm at my wits end with Google's documentation on this - can someone point me in the right direction? I don't want to switch the entire auth flow to use gapi.auth2.authorize, as I do need the user information.
Thanks
EDIT: Is it even possible to access the authorization code? It seems like Google abstracts away that step and just returns the id_token right away. I just need something that looks like:
4/RQFWJLGd3sJQrgxuRaguzJy2yiUV4fAqVGftRSUYuqc

Related

Javascript - Firebase Functions on how to get user id

I want to define custom functions on Firebase using firebase-tools. Is there a way to get userId from firebase-functions?
Say on this code sample, is it possible to get the user who sent the request?
const functions = require('firebase-functions');
exports.helloWorld = functions.https.onRequest((request, response) => {
response.send("Hello from Firebase!");
});
I have tried getting it with the following code unsuccessfully functions.auth.user().uid.
I am quite new to both js and firebase, so go easy on me please, I am trying to learn.
You're over-simplifying the way HTTP triggers work. They have no knowledge of anything about the entity on the end making the request. It could be a user, or just some automated program. The user doesn't have to be authenticated in order to access your function.
If you want to limit access to your HTTP trigger to only authenticated users, you could try something as described in this other question. There is official sample code that shows what you need to do.
Bottom line is this. Unless you do something to safely transmit to the function who the user is (identified by an id token), then you really have no idea who they are.
Think I find a better answer from this post :
https://medium.com/super-declarative/dev-snack-testing-firebase-cloud-functions-with-user-id-tokens-83841d3f06c.
Basically 2 ways for http functions
functions.https.onRequest : You may get, if available, the token from the request and then use firebase admin api to get user UID;
functions.https.onCall for authenticated request : You get it from exposed context object

Google access_token is undefined

I am developing a mobile web application which will access the Google Books API and allow the user to add books to their "favorites" book shelf. Its my first time using an API that requires the Google authorization.
I need to send an authorized request to modify private user data. I (think) I have have the proper access_token but I can't figure out how to get to it.
I am using the Google sign in button like so:
` <div class="g-signin2" data-onsuccess="onSignIn"></div> `
I also have this to identify my application to Google:
`<meta name="google-signin-client_id" content="12345.apps.googleusercontent.com"> `
I sign in with my own Google account and the Google button changes over to "Signed In." I am simply trying to log the access token from there:
` function onSignIn(googleUser) {
googly = gapi.auth2.getAuthInstance();
var id_token = googly.currentUser.get().getAuthResponse().access_token;
console.log(id_token);
} `
I've tried everything I can find in the documentation but no matter what I do, I get back that access_token is undefined.
My suspicion is that I don't actually have an access token, but I don't know how to test that.
What is the correct way to find the access_token? Once I have it, how do I send it to the API?
It's so late but if you pass true parameter to getAuthResponse "getAuthResponse(true)" it returns access_token.
Try using gapi.auth in the API Client Library instead of gapi.auth2 in the Identify Platform. You should find gapi.auth.getToken().access_token contains the access token you need.
That said, I believe this is a bug. If you alert(JSON.stringify(googleUser)) I suspect you'll find there is an access_token field buried in there, but getAuthResponse() doesn't contain it, even though the docs suggest there should be one.
If anyone can confirm I'm understanding this correctly and report it, that would be great.
If you include the response_type in the request header as 'token' it will return the access_token with the currentUser

Facebook Graph API: Client side requests without user login?

I'm trying to get graph api data for public Facebook events rendered in an html document. The site I need to put it on is made with a website builder so I don't have control over the server that generates the html. I can only insert JavaScript code into the page.
The only solution I've found now is by using an app access_token in the client side request:
FB.api(
"/<event_id>?fields=start_time,description",
function (response) {
if (response && !response.error) {
console.log(response.start_time, response.description);
}
},
{access_token: "<app access token>"}
);
I've read through the docs on access tokens
and the JavaScript sdk docs, but the app token solution I've found is not secure (from the docs):
... app access token should never be hard-coded into client-side code.
I don't think the user access token is the flow I want because I don't want people to have to log in; it's only for public events. I don't think the page access token is right either.
Is there:
a way to use the Graph API for public events without requiring a user to log in or without introducing an insecurity?
or a way to make sharing my app access token with the world have no bad consequences?

Get an access token without being connected to facebook

I need to retrieve a facebook page's list of posts (feed) using their javascript SDK, just like they explain in their docs: https://developers.facebook.com/docs/graph-api/reference/v2.4/page/feed
/* make the API call */
FB.api(
"/{page-id}/posts",
function (response) {
if (response && !response.error) {
/* handle the result */
}
}
);
I need it to be my website's "news section", so users should see it even if they are not connected to facebook.
The problem
Cool, but there is a problem... It returns: An access token is required to request this resource.
Holy cow... I'd like to get some access token for you #facebook, but my app doesn't make use of your authentication tools/plugins.
ANYWAY, I tried with FB.getLoginStatus(); but doesn't work, because the only way it can return an access_token is if the user is actually connected to the application. My users may not even be logged to facebook!
So, ¿How can I get an access_token to be stored into a variable, and later be used to get /{my-page}/posts?
I've already payed a look to this SO question, but it doesn't solves my problem, simply because there are no such "generic tokens".
I've also read https://developers.facebook.com/docs/facebook-login/access-tokens/ and that also relies on tokens generated through facebook login methods... So, can't I display a list of fb page's posts in my website, without being connected into facebook, hence an application?
ADD: My app is build with angularJS, I'm not dealing with server-side code. I shall rely purely on javascript methods.
You could either use an page or an app access token, but as you'd be using them on the client-side, neither of them are an option.
See
https://developers.facebook.com/docs/facebook-login/access-tokens#apptokens
https://developers.facebook.com/docs/facebook-login/access-tokens#pagetokens
Note that because this request uses your app secret, it must never be made in client-side code or in an app binary that could be decompiled. It is important that your app secret is never shared with anyone. Therefore, this API call should only be made using server-side code.
I'd strongly recommend to build a simple server-side script (PHP for example) to proxy the request to the Graph API. You could then call this via AJAX for example and load the posts asynchronously (and alse get rid of the FB JS SDK!). There is NO way to handle this in a secure manner if you don't want to use FB Login for all of your users (which also doesn't make much sense IMHO).
I think it's straightforward :)
Since pages' posts are always public, it only needs a valid access token to retrieve page posts.
Quoting what you've written:
So, ¿How can I get an access_token to be stored into a variable, and later be used to get /{my-page}/posts?
You only require an access token.
My suggestion would be;
- Generate an access token for yourself (no extra permission needed)
- request page-id/posts
This way you don't require other users to be connected to facebook, you can simply requests page-id/posts to retrieve posts with access token you generated for yourself.
I hope it solves your problem :D
TIP: As long as posts are public, you only require a valid access token, it doesn't need to be user or page specific.

Using Facebook Javascript SDK to get Graph Data

FIXED NOW! But I can't answer my own question yet. See my comment below. And thanks for helping.
I've searched and searched and read the docs and still can't figure this out.
I have a web page about an event. There's also a public Facebook "event" for my event. I'm trying to use the FB Javascript SDK to get the number of attendees for the Facebook event and add it to the number of people who've registered through the website.
I've created an app and I have an appID and secret string. I can get an access token from:
https://graph.facebook.com/oauth/access_token?client_id=XXXX&client_secret=XXXXX&grant_type=client_credentials
and I can then use that access token to get the attendees for a public event:
https://graph.facebook.com/331218348435/attending?access_token=XXXXXXXXX
That's all fine.
I'm now trying to do this same thing using the Javascript SDK.
I've loaded the SDK and done an init:
FB.init({
appId : 'XXXXXXXX',
status : true, // check login status
cookie : true, // enable cookies to allow the server to access the session
xfbml : true // parse XFBML
});
and I know the SDK is working because I can get an object with the data that doesn't need an access token:
FB.api( '/331218348435', function (response) { console.log ( response ) } );
but when I try to get the attendee data that needs the access token:
FB.api( '/331218348435/attending', function (response) { console.log ( response ) } );
I get an OAuthException: "An access token is required to request this resource."
All the tutorials and information I can find all refers to using the .login method, but I don't want a user to login, I want to login using my app ID without any user interaction.
I'd assumed that the API took the SDK's init request and granted me an access token when I called the .init method, the authentication being done against my website's address (the HTTP referrer - yes I have set my website URL in the Facebook app settings).
Any ideas what might be causing this to not work? How can I get the access token using the Javascript SDK without doing a .login? Am I missing a step? Is this even possible?
Thanks
Form what the rather circular documentations says, getting the attending feed requires a 'generic access_token`. In Facebook terms:
Any valid access_token
Any valid access token returned by our APIs. An access token may not be valid if, for example, it has expired. No special permissions are required. Occasionally, this is referred to as a generic access_token.
So this means that you can use any token you like to access the attending feed, as long as the event is public. The easiest access token to get seems to be an app token: http://developers.facebook.com/docs/authentication/#applogin. You can get this token using only your App ID and Secret, and no user interaction is required.
To summerise the link content: You can get an application access token by sending a GET request to
https://graph.facebook.com/oauth/access_token?client_id=YOUR_APP_ID&client_secret=YOUR_APP_SECRET&grant_type=client_credentials
You can then use that access_token to make the call for you attending list
FB.api('MyEvent/attending?access_token=ACCESS_TOKEN');
Oh. OK.
Well, for whatever reason, I went away and had my dinner and when I come back it's working fine.
When I updated the settings for my app Facebook said it might take a few minutes for the change to get around the servers. Turned out to take over an hour!
My code was fine.
Thanks for your help.

Categories