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.
Related
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?
Up until this summer, I had a website (not my website) which was fetching it's responding fb page posts and was displaying it on a page.
I was doing it using the app-token, which now doesn't work since it now requires Page Public Content Access to get those data, which in turn requires it to be registered as an app, which is beyond the scope of this.
I tried creating a non-expiring user-access token, but they seem to expire after 3 months, no matter the "trick" I tried using.
Is there any suggestion of how I can get over it?
Maybe an automated api call that would refresh the token with no user interaction?
You can either use a Page Token (NOT a User Token) for the Page if you manage it - but it will expire. There is no way around that. OR you apply for Page Public Content Access so you can use an App Token.
Auto-refreshing would make the whole point of expiring Tokens pointless, you need user interaction for that.
So, I did it!
Now the how: I did it with the manage_pages access, not with Page Public Content.
I went back and forth a total of 5 times to get this to pass and a bit over a week.
First of all Page Public Content is only allowed by Facebook when you want to analyze data from other pages as well, so you better not mess with it.
What I had to do to get the request approved is specify on your application for requesting the access that there is no login, provide a copy of your code on the description and I also included a url where it was working with a user generated token through javascript, so they could review the code through a web debugger.
After that you get a manage_pages token which you can use to fetch your pages posts
I really hope some of those things were an overkill, but, like I said, I had to submit a review a total of 5 times, so on the last try I went all in...
I'm currently playing around with a KnockoutJS SPA template in ASP.NET Core 2.1, and I managed to implement an authorization flow exactly as this one which was made in Angular:
https://fullstackmark.com/post/13/jwt-authentication-with-aspnet-core-2-web-api-angular-5-net-core-identity-and-facebook-login
As you can see in their User front-end service, basically the only check for whether the user is logged in on the client side is the check if the "auth_token" key exists in the client's local storage:
https://github.com/mmacneil/AngularASPNETCore2WebApiAuth/blob/master/src/src/app/shared/services/user.service.ts
this.loggedIn = !!localStorage.getItem('auth_token');
// ?? not sure if this the best way to broadcast the status but seems to resolve issue on page refresh where auth status is lost in
// header component resulting in authed user nav links disappearing despite the fact user is still logged in
Simply put, anyone can open up the browser local storage and insert a random string with the "auth_token" key and they'll be able to see everything admin-related in the UI (even though they will fail on API requests).
Can someone suggest a better flow for this? Or is the only option to send a "log in request" to the API, whenever an admin page is "opened"?
P.S. I am relatively new to the authentication schemes front, should JWT perhaps not be used for client-side content validation?
Considering JWT best practices, all your validations should be done in your back-end, since any validation coded in your web app could be read by any of your clients, resulting in a huge security flaw: anyone would know how to create a valid JWT for your application.
Is it a big problem to be possible to see your admin-related UI, even without any data? Considering that all of the routes which can return sensitive data are protected by JWT authorization, if a user access any pages or parts of your UI which require data, they would trigger a request to retrieve it, which would probably return a 401 (Unauthorized) HTTP status, or similar. A common front-end practice in these situations is to erase client user data, and redirect to a login page.
So, a typical flow would be:
User inserts a fake access token into their storage
User opens an admin page/ui which uses sensitive data in any way (showing, using for any internal logic, etc)
Web app does a request to the API requesting data
API returns a response which will be interpreted as an authorization error
Web app receive the API response, erase user access token and redirect them to its login page
In most cases, this entire flow will happen fast enough to block your user to further interact and explore your web app.
Would be better if you provide more information about your scenario, so anyone could understand if your worries are something that needs to be considered and truly solved. However, in most cases, the behavior above is accepted.
I'm currently using a NodeJS server. I verify a condition with a if statement. If the credentials are not valid, for example, how to send the user to a specific page?
if (credentials) {
// go to the main page
}
else {
// go the login page
}
You've said you're using ExpressJS. In ExpressJS, you do a redirect via res.redirect:
res.redirect([status,] path)
Redirects to the URL derived from the specified path, with specified status, a positive integer that corresponds to an HTTP status code . If not specified, status defaults to “302 “Found”.
First, you need to establish what kind of authentication you are using. There are a million ways to do this, but if you are less familiar with auth systems, I would recommend using a third-party auth system like Facebook or Google login. Those would generally give you some kind of auth token on login, and essentially you could just check to see if the stored token is there, whether that be in cache, cookies, local storage, etc., and if it has not expired. If all is good, keep going, if not, then redirect to the login page.
If you want to make this more secure, don't write any of credential validation on the client side. Have the client's browser check for the auth token and its recency, then send it to the server. The server would then respond by routing you to the proper page.
Another method that should probably be used in tandem with this would be to check for a valid login on every single page where the user would need to be logged in, as opposed to only having the one page that redirects to either a login screen or where you want to go.
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.