I am having a bit of a hard time wrapping my head around how to connect to my OAuth2 Freshbooks API from my bot. Currently I have my API set up such that hitting the /auth route will take the user to the Freshbooks login page and once successfully authenticated the token is returned back to the user. After we have the token the user can get all of their invoices in my web app.
Now, when I build a DialogFlow bot, how do I go about this? What I have thought about is that the user first hits the /auth route which returns the authorization URL which the user can then open in their browser and log in...but after login, how do I return back to my bot?
After a successful login, the /callback route is called by my api with the authorization code to get the token...but this will not be returned back to the bot since it is all happening in the browser...I think.
What is the best approach for this?
Also, after getting the token from my API, should this be stored in a context in my bot?
Thanks for the help and sorry if this is a beginner question. I tried finding an answer online but I just cant wrap my head around this one.
Assuming that your OAuth service is configured correctly you don't have to worry about any of this. The procedure works roughly as follows:
Account linking is triggered via one of two ways:
If you need a linked account to fulfill a certain intent you can simply check the Sign in required box of that intent in the Google Assistant integrations page in your Dialogflow project. If you check this for all intents that are listed for invocation the user can only use your agent once they have an account linked.
The other option is to manually call the sigin helper. This can be done at any point during the conversation, i.e. it does not have to be tied to a particular intent.
When the account linking procedure starts the Google Assistant will load your login page in an in-app browser.
Once the user has authorized your client the OAuth service should (like any OAuth service) redirect the user back to the client. On the Google Assistant this happens via a redirect url of the format https://oauth-redirect.googleusercontent.com/r/<google developer project ID>.
After that Actions on Google calls your fulfillment service with the original intent (the one that triggered account linking), only this time with a valid access token for your service.
Such an access token will from now on be included in every fulfillment request your receive from Actions on Google. You do not have to store this token, you should always use the one that is send in the request.
For more details see the Implement Account Linking documentation.
Related
We have a web server using Google Sign-In to authenticater and authorize for API access (Classroom). We need the sign-in part, so we're using init() and signIn(). We cannot use authorise(). Also, we're not signin in with particular scopes, as we just need identify for normal usage.
The logged-in user can enable a feature that requires offline access on behalf of his/her account to the Google Classrom API. We call grantOfflineAccess() with two scopes related to Classroom to get an authentication code, which is stored for later.
On the server side, we have a gRPC service that doesn't expose any web front-end. We're using C#/.NET with the Google API Client libraries.
I implemented an IDataStore that can respond to TokenResponse requests by either calling AuthorizationCodeFlow.ExchangeCodeForTokenAsync with the above code, or return the last TokenResponse stored in the database. When (well, "if") IDataStore.StoreAsync is called with a new version (normally after a token refresh was required), it saves it again in the database.
My problem is that ExchangeCodeForTokenAsync returns me a TokenResponse without a refresh_token. This means the access_token is only valid for 60 minutes. I would need to intercept exceptions at the service call level to call ExchangeCodeForTokenAsync again (if that works!), instead of relying on the Google API Client Library handling refreshing automatically all nicely.
What could be preventing ExchangeCodeForTokenAsync from returning me a refresh_token?
Thanks.
Well, I found the answer in this other question.
The refresh_token is only provided on the first authorization from the user. Subsequent authorizations, such as the kind you make while testing an OAuth2 integration, will not return the refresh_token again. :)
I simply removed my app from my Google account's authorized apps, and my next ExchangeCodeForTokenAsync call returned me a refresh_token.
I've been reading up on token based authentication for a project that's part of my trainee-ship. My task is to implement some sort of user authentication and we've settled on token based authentication.
Now I get the basic principles, like passing the token in the xhr header for xhr requests. But I do not understand how you would pass the token on an initial page call.
Let's say we're working on a single page application with a navigation bar that has a login button for users that are not currently logged in, and a profile button for users that are logged in.
Seeing as that navigation bar is delivered on the initial call of the website, how do I know how to serve the right button to the user? From what I can gather I can pretty much only authenticate on xhr.
Do I have a misunderstanding about token based authentication?
A little clarification:
Assume a User already is logged in and has received a token from the Server.
He then closes the Tab and later goes to my app again.
At this point, server-side I do not know the user, as I could not have sent the token at the initial request.
A coworker suggested using AngularJS' onload to send the token after the initial page load to verify and get my JSON data from the server, which is then used to create the app with Angular
Also the point of the project is to not use an existing library like JWT, so I can actually grasp the concept and the inner workings of such mechanisms.
I am using the YouTube API 3 for my app. When a user logs in for the first time he/she is asked to give consent for the app to access their YouTube account.
window.location = 'https://accounts.google.com/o/oauth2/v2/auth?
client_id='+client_id+'&
redirect_uri='+redirect_uri+'&
scope=https://www.googleapis.com/auth/youtube&
response_type=token';
If the user logs out using a request to https://accounts.google.com/o/oauth2/revoke?token='+token, the default behavior is that when they are redirected to the first link above, they are automatically logged in without being required to click for consent. I want the user to re-approve the application for YouTube access each time after logging out.
As described in the docs, I added the parameters prompt=consent&include_granted_scopes=false to the url request, but this only prompts the user to re-allow Google offline access. It does not re-prompt the user for YouTube access.
How can I get the auth link url to request permissions for the YouTube API scope on a repeat login?
Please try revoking a token wherein part of the removal process can include an API request to ensure the permissions granted to the application are removed.
To programmatically revoke a token, using HTTP/REST, your application makes a request to https://accounts.google.com/o/oauth2/revoke and includes the token as a parameter:
curl https://accounts.google.com/o/oauth2/revoke?token={token}
Important Note: Following a successful revocation response, it might take some time before the revocation has full effect.
I need to access status updates of an artist page to display as feed on my website.
So everytime a user accesses the artist' space on my website, he sees the artist's status feed in a tab.
Do I need to ask for the artist's permission every session? That would not be practical I guess.
Thanks
You only need to ask permission once, when the user logins for the first time.
If you use the client side JS SDK, that is really all you need to worry about. The access_token will be automatically refreshed by the SDK whenever needed. The user only needs to be logged in to facebook, no action is required.
You will most likely be using the JS SDK.
So unless you use a manual server side oauth flow, see below:
If you use a manual server side oauth flow you usually get a short-term access_token that is valid for 2 hours after the user logs in for the first time.
You can request a long term access_token by sending a request to oauth/access_token with some additional parameters:
See here:
https://developers.facebook.com/docs/facebook-login/access-tokens#extending
This long lived access_token is valid indefinitely, but may expire at ANY moment.
Reasons could be:
user password change
user logout
use de-authorizes app
...
So you are to just reuse the access_token whenever you want to interact with the users facebook account ( you don't have to ask them to log in again).
But as soon as your access_token becomes invalid, you have to update the acces_token by sending the user trough the oauth flow again.
So I'm developing my own API for my website - I'm mimicking the Facebook JS SDK in regards to how my system works. API client displays a button, popup comes up and the user can log in. Login popup issues an event to the opener window and the parent window now knows the user is logged in. That all works.
What I'm having trouble understanding is how they can verify that the refresh requests are valid. If the API client needs to send a request to the server to ask if the user is logged in and it's all in JS, then everything is transparent. The API client says, "Hi, I'm application 4jhkk2l3bnm389, is the user that's logged in on Facebook also authenticated with me? If so, can you send me a new token so I can make API calls?" and Facebook says, "Oh, you're application 4jhkk2l3bnm389? Yeah, the user is logged in and has allowed you to access their information, here's an access token."
But how does Facebook prevent an outside application that isn't the authentic application from saying, "Hey, I'M actually application 4jhkk2l3bnm389, I promise I'm not lying. Can I have an access token?"
I have no idea how they determine the difference. Obviously if it was all done through AJAX calls in modern browsers then you could just provide an Access-Control-Allow-Origin header. But if a malicious client were to use cURL then I don't think I could ever tell the difference. How does Facebook do it? A good explanation is much appreciated! Thanks!
All access tokens belongs to an app/user pair, and in order for Facebook to return such an access token to the app, these has to be verified.
The app, or client_id, is verified against the domain specified in the redirect_uri - if the page tries to use a client_id/redirect_uri pair it does not own, then it will not receive the access token as this will be passed to the valid redirect_uri (the mechanism the JS SDK uses follows the same rule).
The user, or uid, is verified using the cookie Facebook sets when you sign in.
While you can easily spoof the client_id/redirect_uri pair using curl, the same does not apply to the uid, as you would have to be in the possession of the users cookie. And if this is the case, well, then you could simply grant your own application access.
Facebook uses OAuth 2.0 for authentication. You can find details of how Facebook deals with OAuth right here: https://developers.facebook.com/docs/authentication/. There are many different ways OAuth can be used, depending on whether you're on a mobile device, a page on facebook.com itself, or, in your case, just a web page outside of facebook.com. The details of that final flow can be found here: https://developers.facebook.com/docs/authentication/client-side/.
Basically, Facebook knows what applications you have given permission to view your information. When you run one of those applications, they first make sure you are logged in to Facebook, then they request a user access token from Facebook, essentially saying, "Hey Facebook, I don't know this person, nor should I. Can I get access to their information?". And then Facebook looks internally and if it decides this particular application should have access to this user's information, it sends a user token.
That's the simple way of describing it. There are many different ways the authentication flow can happen, depending as I said earlier on what kind of device the request is happening from, whether this is a page on facebook.com, etc., essentially based on your security constraints. Best to read the Facebook authentication docs referred to earlier for the details since it can get quite tricky.