I am building an Single Page app using angular.js and I am facing this issue for which I am not able to find the right answer.
When we do a full page refresh in an angular app, how should we check if the user still has a valid session ?? State Provider or UI router merely routes the url to the requested page, but what if the session of the user has expired ?
One thing that comes to my mind is to use a service and store a Boolean value there once the user logs in and on every page refresh or state change, we check this Boolean and redirect the user to login page, if this value is false. But, if we do a refresh, this Boolean value is reset.
Thought of storing this key value in a cookie or html local storage, but how safe are these values getting stored here. Some one can reset the value of this Boolean to gain access to a page.
Please let me know.
To make a client-side app secure you will need to involve a server of some sort. Storing values in cookies or local storage will not do any good as these can be manipulated by a user (as can everything else on the browser).
Not sure what options you have available to you but I would recommend looking into Nodejs/Expressjs/Passportjs - this is a pretty awesome combo and very good support here on SO.
Once you make progress in this area you will then be in a position to ask a more focused question.
I think you're conflating a few concepts here.
One - is the user authentication to the server. It must be the server, otherwise the concept of a user session in a client-side-only app is useless. This is facilitated (typically) by an authentication cookie. The cookie is a security token given to the user and signed by something secret on the server. The cookie contains things like login name and expiration. The cookie is validated by the server on every request the browser makes.
Two - is the nice user experience maintained in the client-side app. What I mean by that, is that if you didn't check whether the cookie has expired, your ajax calls to the server would (and should) fail with HTTP 401 - Unauthorized. You likely would want to prevent that, and have your app preemptively redirect to a login page, or if applicable, request to refresh the security token.
So what does all of that mean?
Enforce authentication on the server
Create a loginService that checks session expiration from a cookie, or whatever else you use fo your user authentication.
Use resolve parameter of $routeProvider or $stateProvider to have the loginInfo available to controllers. Here's my answer on SO to a question you might find useful.
Related
I am building a simple application with base64 token authentication. To be more secure, one should use CSFR protection. Additionally I want to avoid any kind of framework or library to really understand every step.
I arrived at the point where I send a fetch request with an "Authentication: Basic <base64 token>" header. To store that token you need some sort of state management, cookie or localStorage solution. For simplicity I landed on sessionStorage, but I immediately saw the danger:
On the admin page I had a if (!sessionStorage.token) window.location.href = "/"; statement. That could easily be manipulated with the browsers developer tools.
That got me wondering, how do you actually validate an active user session?
the cookie name could be set with the developer tools
obviously any kind of localStorage / sessionStorage solution, too
Is it really just possible with a state management solution?
Does the content of a cookie need to be validated with an additional fetch request?
Could I simply pass the token alongside the GET request for the admin page and be done with it?
While building a javascript SPA (single page application) I need to display some pages differently based on if the user is logged in or not.
Auth is handled by JWT which is served via httpOnly cookie and secure headers.
That leaves cookie not accessible from the SPA javascript and that in turn means I don't know if the user is logged in or not.
I did check some posts on how to solve this problem and found some suggestions like
send another cookie which is not httpOnly with some flag like session ID or user ID with expiry date and in the client side JS, use that cookie to see if the user is authenticated.
create an endpoint on API server, something like /is-logged-in and make a http call from JS to check if the user is authenticated or not before displaying the page.
store JWT locally without cookies (obviously a no go due to the security reasons and the amount of code I will have to write to mitigate all kinds of possible stealing attacks)
I am late to the SPA party but I am sure this has to be a long solved problem. I am unable to see something obvious I guess.
Please point me to the right direction.
For completeness, here are some unanswered, semi answered related posts
Send a GET request on page load only if user is logged in
How to find out if user is logged in having httpOnly JWT token cookie?
JWT in httpOnly cookie - AuthGuard and protected routes (Node.js, Angular)
http-only cookie + token : double job?
You have basically two choices:
Save that the user is logged in with a second non-http cookie that expires
Pros
No addition HTTP request required
No latency before you know if the user is logged in
Cons
You need to keep the expiration and renewal of both cookies in sync
If your cookies are not in sync anymore because of an edge case, you will need to detect it and act accordingly
Use an HTTP request that will tell you if the user is logged in or not
Pros
Less error prone
No need to change the backend
Cons
You still need to detect if the user is no longer logged in while the user is using the app
Currently I'm working with -
Django REST Framework
Angular 5
RxJS +
OAuth2
The list of paths of all components except the LoginComponent I have AuthGuard where I check whether the data on the token and the user in the localstorage of the browser.
If data is available I will return True. But as soon as the token expires, I can't do anything with the user.
If I get a 401 code in the service, I can't even redirect the user to the login page since I can't use the router in service.
Basically I am wondering how, when and where to update the token in my web app?
Kindly give some knowledge on how to work with tokens. Also it would be helpful if any code example is provided.
You question is too broad, and opinion-based. But if you want a thrid party point of view, here are my two cents :
Storing the Token
Depending on your application, you have several ways of storing a Token.
LocalStorage
The first solution, the one you used, is storing it in the local storage. This way, the Token will remain on the device as long as you (or the user) doesn't delete it.
Session storage
The session storage will behave same as local storage, except that the token will be deleted once the user closes his session.
Service storage
Last option : storing it in a service : your token will remain as long as your user stays in the scope of Angular (meaning, doesn't reload or change tab).
How to chose ?
Depends on your application. If you make an application involving high risks after login, then you should consider using the session storage, so that the user gets "removed" as soon as he leaves the page. For a casual application, stay on the local storage. And if you REALLY want to lock your application up, use the service storage.
When to store the Token
Seems obvious, but you should store it when the user logs in.
Update the Token
You should not have to do that. The Token matches an user, or an user session. The only update you should do is a deletion, not a rewrite.
Where to update the Token
In a service dedicated to Token management. This is the best practice.
More information
You said you had an Auth Guard. This is a good practice. but yes, you can redirect the user from your service. Why wouldn't you ? That's the usual way of asking an user to connect ! Use the router in your service, really, there's no issue with that.
From my point of view, and what you described, except for the routing in a guard, you're doing it pretty well. The only advice I would give you is to handle an expiration date on your token, if your application is high risk profiled (and you have to use the session storage).
I create js app with Backbone and RequireJS for registred or non registred users. To retrive data from database I use simple JSON web service and of course some of methods are not avaiable for quest. Problem is that I don't know where or how I should store auth data retrive from server without reloading it in every view. Should I use cookies ?
I guess it depends on your authentication, authorization methods as well as the kind of security you need to consider for your users. If you're trying to be RESTful, you can't have sessions to save state (at least server-side). You could, but it wouldn't be RESTful due to saving of state on the server, if that matters to you. I've heard that it is okay to save state client-side but from what I've read, I'm not sure how the community feels about certain implementations that take this approach. (Like cookies, I'll revisit this later.)
Say you have someone login with username and password. You can hold that information in your Backbone app, maybe you have a model called AUTH that does this. Each time you make a request to the server you'd send that data each trip at which point the server authenticates and gives or rejects access to given resources. If you use Basic Auth this information would be in the header I think. Using SSL mitigates some of the major security concerns surrounding the sending of this information over the wire and for the rest of the discussion let's assume this is what we are using.
The other way that you could do this is to use encrypted cookie, encrypted cookie sessions. This is what I do with my current application. Honestly, I don't know if this is considered a violation of RESTful principles or not. The general chatter on the web seems to be a lot of "cookies bad, sessions bad" with some people saying, "get real." Using cookies would expose you to cookie hijacking if someone had access to the users computer, but depending on your application and the security needs it might not be an unreasonable option. It works for me and if it isn't RESTful, I like to call it RESTLike.
To close I'll just describe my setup. It would be nice to get your thoughts as well as the Stack's opinions on this also.
Basically I have a setup where when someone goes to the main page, the server checks for the encrypted cookie session. If the cookie session is invalid or non-existent, it gives the user the regular page with a chance to login. When they login, I send that information over POST so it's in the body of the request rather than the URI. (This is technically a violation of the REST HTTP verb concept since you use POST to save a resource.) When that information is processed, check the username, pass hash created by a unique salt, then the server creates an encrypted session cookie and passes it back to the user. Now, each time my user hits a route that requires authentication, the server checks the cookie to make sure it is still valid (time limit, user information, etc.) and if so - allows access. If not, it destroys the cookie information and sends back an appropriate status code. The backbone app reacts to this by resetting any view and data that shouldn't be in the hands of an unauthenticated user and shows them the login screen.
Hope this gives you an idea. This is the answer to how I do it, but if someone has criticisms or better ideas I'd be happy to upvote them instead.
I am creating a chrome extension, rather a chrome webapp. This application just contains the html, js, image and css files. The application connects to a server to fetch data. I chose to do this as it would reduce the amount of files downloaded by the user. Using Backbone.js I have an MVC architecture in my application. Thus the application just sends json.
Now having said this, I need a session management. I plan to use Google authentication as the organization has Google Apps. I need a method that once the user has logged in using google auth the server get the user name every time the application makes a request.
Is it a good idea to add the user name in request header, if possible. Or should I use cookies? Can any one tell me how I could go about using cookies in this case?
This might be a late response but I want to present a more elegant solution to you given that the user has cookies enabled in their browser.
First read my answer on another question.
Now that you can send cross origin xhr from your content scripts all you need to do is store all your authentication and session management at server only. That is right, you just need to display whether the user is logged in or not and a logout button at client based on server response.
Just follow these steps.
At client Whenever user accesses your chrome web app, blindly make XmlHttpRequests to your server without worrying about authentication, just keep a tab on response from server which I describe below.
At server whenever you receive a request check for valid sessions or session cookie. If session is valid send proper response, if not send error, 401 or any other response to communicate to your client that session is not valid. It is better if you send an error code like 401 since then you can put a generic script at client to inform them that they are not logged in.
At Client If response from server is proper, display it, else display login link to your website.
IMPORTANT: Display logout button if user is logged in.
Check out my implementation of this in my extension
For help using Google authentication in your app take a look at Google's OAuth tutorial which comes with all you need (took me no time to set it up using this).
As for session management. The implementation of OAuth used by Google stores the tokens in localStorage. Also, as briefly mentioned in the extensions overview we are expected to use localStorage to store data. Thus, I suggest you store the users name here as it will be accessible throughout the app's lifetime (until it is uninstalled). However, you may need to manage the name stored here and consider what should happen when users log in and out. That said; I'm not sure if sessionStorage would be a better option as I've never used it before, let alone in an extension.
Note
localStorage and its counterparts only store strings so I suggest using a wrapper which uses JSON to parse and stringify to get and set your values respectively.