My application is writing/reading files to/from Google Drive. Before I can access the files I need to get a token that would be passed with the request. I am using googleapis node package.
The flow is as this:
get auth url:
the front end sends request to my api
my api requests the auth url from Google with
(new google.auth.OAuth2(
creds.GoogleDrive.clientId,
creds.GoogleDrive.secret,
'http:localhost:3000/ifr'
)).generateAuthUrl({scope: 'https://www.googleapis.com/auth/drive'});
the received url looks something like this:
https://accounts.google.com/o/oauth2/v2/auth?scope=https%3A%2F%2Fwww.googleapis.com%2Fauth%2Fdrive&response_type=code&client_id=<...>&redirect_uri=http%3A%2F%2Flocalhost%3A3000%2Fifr
this url I return to the front end and set the source of the iframe to it
If a user has already gone before through the steps of consenting to my app accessing their Drive, then google redirects to the provided url, i.e. http:localhost:3000/ifr, in this case, and adds code query sting parameter, which I then pass to my api to get the token from google. This token is later used to create google.drive object that gives access to the drive (this part works fine, though maybe there is a way to avoid going back and forth between client and api?)
If a user hasn't consented yet, then the above url loads google's page where the user has to click through a few confirmation buttons and after they agree to everything, google redirects to http:localhost:3000/ifr?code=.... And this is where I have a problem. In this scenario google's confirmation page wouldn't load in the iframe, it gives me a "broken" page. I don't see a way to distinguish between the url that would load the consent vs the one one that redirects with code, they look the same, so I can't load one in the iframe and the other in parent.
How are these pages different? Why one is ok to be loaded in the iframe and other one isn't? Maybe I am doing this all wrong and the whole authentication can be done server side?
Related
I´m trying to build a pure JavaScript app, This app does call to an API, and that API return a token which I will save in a cookie (any advice about it?).
I have many doubts, the most important are the following,
How should I make the redirect stuff between pages, and how I prevent that someone access to my page, I want to do something like if there is not cookie (token) and the token is invalid (I will check the token before show the page), redirect to login, if is all correct, show the home page for example
Since you have your token in a cookie you should start page load with an API call that verifies session. If API returns false simply redirect user to login page, otherwise execute rest of your javascript. I assume your sensitive data will come from subsequent API calls that should also verify the token.
You probably understand that you can't protect the static content using this method since anyone can add breakpoints on browsers and modify the JS code to their preferences (as in remove the forced redirect), so your focus should be on loading everything you want to be hidden through ajax API calls that are secured with token.
I have Single Page Application, browser only webapp (javascript, no server side).
The user interacts with the application and sets some variables.
Far after the creation of the main index.html page, when the user wants to upload a file, he needs to authenticate with an external service using oauth2 (using "token / implicit grant").
Once authenticated, the authentication service responds with a redirect, possibly to another page (page2).
What should the page2 do to continue the flow of the program?
Should it redirect back to the original main page (this time, with the access token)?
If so, wouldn't this reload the main page and reset the application and the variables that were set?
Thanks,
Avner
EDIT
Ricardo,
I don't use a specific web platform, just plain javascript.
#charlietfl
I found a general example here that does postMessage between 2 seperate windows and it works ok.
I'm straggling to customize it according to Ricardo's comments, i.e.
make the second window popup
set a separate HTML file or a "noop" route on your SPA as redirect URL (what is a noop route?)
poll for that URL in the popup
I found this example that create the popup in the main page (index.html), set the redirect, and poll in order to close the popup.
In my case I set the redirect URL to a new page (auth.html) that does postMessage with the access token back to the main page (index.html).
If the auth.html page is not openned in the browser, should I still expect to receive a message in the main page index.html ?
From what I read for postMessage to work both pages, index.html, auth.html should be opened in 2 separate tabs in the browser.
You can use a small popup, which will load the necessary oauth2 endpoint, setting a separate HTML file or a "noop" route on your SPA as redirect URL. You may then poll for that URL in the popup, so you know when to close it (user is done with oauth2 flow).
This strategy is used by libraries like vue-authenticate, react-oauth and satellizer.
Also, depending on the specific service your are trying to authenticate against, you can find official libraries and SDKs that will handle the oauth2 flow automatically.
Last but not least, you could also save the current state of you application in browser storage, redirect to the oauth2 endpoint, and point back to your app as redirect URL. When coming back to your app, the specific route should be able to restore the saved data and resume user experience, with the addition of the oauth2 tokens.
I'm trying to change my Tamper/Grease monkey userscript to pull updates from GCS. While this is usually trivial if the storage is public, the file URL requires verification that the user is a member from our domain. There in lies the problem.
If the URL is accessed via the browser, it bounces around some redirects for Google Auth, and eventually retrieves the file and will "remember the login" for some time. This is a manual intervention process and is not a transparent solution.
If I pull the file when auth isn't known (ie: new browser), I get a 302 redirect, which when run under the userscript scope in TamperMonkey is simply treated as an error, and not followed (This is part of the RFQ from memory).
Now, if I use the script to push the URL as a link in the page, the link works (domain auth already in use to access the page). If I use the script to access the link, the tokens aren't available (guess?), and so a 302 takes place, and because it's in script land, it silently fails.
I'm looking to find out what JS I need to import, to pull any required auth tokens that the user already has, and send them along with the request to the GCS location. Note that Google Auth is required to be using the underlying website, and usernames will be on the required domain.
The GCS file has Domain:Reader permissions set with our domain listed.
I have a facebook app that requiers authorization, therefore I have to pass a redirect url along with the authentification-request.
My app is entierly front-end code.
If I wan't the standalone-version, I can just pass the window.location.href
Something like this won't work for the app-page, because it's iframes from different servers. Therefore I have to hardcode the app-url in this case.
The app is intended to be embedded on different app-pages, so I can't hardcode that. Apperntly I can get the facebook page-tab-link etc using the facebook api. Haven't looked in to the details yet though. Redirect back to page tab after user authenticates?
As facebook doesn't allow parameters, my plan is to add /pagetab/ or /app/ to the end of my url, and add that to the various urls in the settings of facebook. After that I will create different cases for the different url-endings.
Although this soultion sounds like a lot of work. Is there a better way to do this?
If your app wasn’t totally client-side, then you could find the info which page your app is embedded on in the signed_request parameter. But since Facebook POSTs that to the iframe on calling your app, there is no way of accessing it client-side.
As facebook doesn't allow parameters
Facebook allows for a parameter called app_data in the URL, which is passed on to your app. But again, this happens via POST on first page load.
If you were willing (and able to, regarding your platform) to make the little adjustment of having your apps HTML code generated by a server-side language (instead of it being purely static HTML pages), then you could easily evaluate the signed_request parameter, and have the page id written into a JavaScript variable, so that you can use it client-side from there.
Here is a permalink for a tweet on twitter:
https://twitter.com/#!/917thebounce/status/144914597537787904
Notice the hash symbol in the url. When I enter the url into Facebook's debugger tool:
https://developers.facebook.com/tools/debug/og/object?q=https%3A%2F%2Ftwitter.com%2F%23%21%2FHYPERCRUSH%2Fstatus%2F144920720378568704
it appears as though twitter is sending back a 301 Redirect to a permalink that DOESN'T have a hash symbol. When I view the original link in my browser, I don't get the 301. I understand that the reasoning behind sending the redirect is so that it gives Facebook a proper url to scrape data from.
a) How might the twitter application know to redirect the Facebook scraping application but not a normal user visiting via a browser?
b) More importantly, how in the world might twitter know which non-hash url to redirect to? Since to my knowledge an http request does not include anything after the hash symbol, i.e. doesn't twitter only receive a request to https://twitter.com/? I must be wrong here.
Actually, its a "shebang" and is used to javascript based navigation. This is a google thing, so urls with shebangs actually can be indexed.
You should be able just to remove it and the request it through facebooks debugger tool, which means you should be able to send https://twitter.com/917thebounce/status/144914597537787904