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.
Related
I'm trying to auto logout an app if user logged in from another tab or browser.
I'm using react-idle-timer and Parse Server.
I'm not sure if this line of code will be useful
Parse.Error.INVALID_SESSION_TOKEN
I can access session token via localStorage
const res = await Parse.Cloud.run('login', values);
console.log(res.session);
You can't differentiate a request from a different tab within the same browser. It will share the same session token and be indistinguishable from any other request. Requests made from different browsers will have different session tokens and if they store some user info you can determine which ones belong to which user.
If we reframe your question it sounds like you only want to allow for one active login per user. This requires a centralized or clustered session management solution that supports preventing multiple concurrent sessions.
If you will only ever have one backend server or you are using a shared database to store sessions, then you can do this a bit easier depending on what you are using for session management since all sessions will be available on the one server.
It is not clear to me if your users are connecting directly to parse server. If they are you will most likely need to modify parse-servers code directly to support this.
In general this is a silly idea. Unless you have a legal requirement to do so I would not advocate worrying about this. Bypassing this is usually as easy as copying around a session token.
I am using ember to write a web ui for a site that requires user to log in. Suppose the browser has stored some cookie from last login of a user. Now the user visits the site again. So, is it a secure and common way for ember to log the user in automatically based on the cookie from the last visit? If so, what are the common ways to implement this? (I can't find anything from Google.) Furthermore, how do I create the cookie upon login? Is it a common way to just put a user id, password hash, and expiration in the cookie?
Additionally, any references related to this subject are greatly appreciated.
Edit 1
In light of Vohuman's answer, I think I can make my question a little more specific. Basically, what I want to know is a common and secure implementation to keep a user logged in, even when they close and reopen the browser. Namely, the life time is beyond the session scope. Take linkedin for example. If you are logged in and exit the browser. Then next time you revisit linkedin, you are still logged in automatically. Right now, what I can picture is a solution like the following.
When you first log in to the site, the server will return a cookie which includes an authentication hash token. Then next time when you revisit the site, the server will receive the hash token and thus authenticate your session.
So, is above flow basically what people usually do to keep a user logged in? If so, is the JSON Web Token (JWT) basically one way to construct the hash token I mentioned above? Additionally, assuming the connection is HTTPS, this approach seems secure to me. Is it not?
Edit 2
This article gives an interesting discussion regarding where to store the access token.
is it a secure and common way for ember to log the user in automatically based on the cookie from the last visit?
Yes and no. Security is a complex topic. Usually session cookies are used for authorizing users. This is actually the most used method of keeping the users logged in. If the user can't keep his credentials secure then any layers of security can be vulnerable.
For Single-page applications usually access tokens are used instead of cookies and sessions. The client sends the user credentials and server returns an access token. The token is encrypted and expirable and can be stored in localStorage or sessionStorage. Using JSON Web Tokens (JWT) standard is a popular method for implementing user authentication and authorization in web services. As an example, the Facebook Open Graph API uses access tokens.
JSON Web Token (JWT) is a compact, URL-safe means of representing
claims to be transferred between two parties. The claims in a JWT
are encoded as a JSON object that is used as the payload of a JSON
Web Signature (JWS) structure or as the plaintext of a JSON Web
Encryption (JWE) structure, enabling the claims to be digitally
signed or integrity protected with a Message Authentication Code
(MAC) and/or encrypted.
edit:
So, is above flow basically what people usually do to keep a user logged in?
For traditional websites, yes.
The whole point of using access tokens is keeping the web service/API stateless. This means that server doesn't have to store any cookies/sessions for authenticating and authorizing users. The stateless is one of the key factors of implementing web services that follow the REST paradigm. It's client that has to store the token and send it to the server (via the Authorization header or query parameters). The server doesn't store the token. Of course, you can store the tokens on the server if you want to add another layer of security, but it's not so common and not necessary. Storing the tokens on the server can also make your application vulnerable to database attacks and is not recommended.
If you want to make the process more secure you can decrease the validity time of access tokens (1 hour, 1 day or 1 week, it's up to you).
As for localStorage, is it secure?
localStorage data are stored separately for each origin (domain). A malicious user can only read the data if he/she has access to the user browser. You should make sure that your app doesn't have any XSS vulnerabilities so malicious users can't inject any scripts to your application. This is actually a different topic.
I'm making a google-chrome-extension for a certain website, and want the browser_action to display the number of notifications a user has received on said website.
Currently, I am using an ajax request to retrieve the HTML from the website/messages page, and then I am using jQuery to count the number of "#unread > li" elements in that HTML (each one representing a new message.)
Now, I take this number and display it on the browser_action icon.
All works perfectly, the correct amount of messages are notified, BUT the user must be logged in on the site (not my site) for it to work properly, otherwise they will think that they have no messages.
I was thinking that I could detect if the user is logged in, and if not display a red ! exclamation mark on the icon. Then, when the user clicks to show the pop-up, it asks them to log in.
However, I have no idea how to actually log the user in to the website using this method: how do I send the credentials across? Or does the website have to support a request like this?
TL;DR
How can I log a user into a website I don't own remotely?
Disclaimer: I've never done a google chrome extension, but based on the rest of your question, it sounds like it's just working with JavaScript like any other web page, so I'll go ahead and answer it.
In any case, working with cookies in JavaScript can be somewhat of a pain:
https://developer.mozilla.org/en-US/docs/Web/API/document.cookie
http://www.perlscriptsjavascripts.com/js/cookies.html
I'm assuming that your server side already works with and expects cookies, so I won't try to suggest any alternatives. That being the case, your server is what needs to validate the cookie, so, IMHO, might as well set the cookie on the server side. If the server handles it, on the JS side, you simply post the username/password to a server-side page, e.g.
$.post("/user/login",{"Username":"foo","Password":"bar"},callback);
That server-side page validates the username/password and then, if successful, generates the cookie and sends a response back to the JavaScript (e.g. {"IsSuccess":true}). Upon receiving a successful response rather than an error, you just start calling the other web services to retrieve your data assuming you are logged in and build out the page.
Assuming that your web services will return HTTP error codes that help you determine a problem with the session, if you get a 401 error code, you take the user back to the login page. If you get a 403 error code, you let the user know they can't access that data...etc., all depending on your app.
Ultimately, JavaScript doesn't know whether a user is actually logged in, so you have to rely on the server to send you information in a way that is understandable so that you can direct/prompt the user as necessary.
[Edit: 2014-11-21]
You didn't answer my other question: what do you get back? If they don't set the cookie themselves at the login, then you need to get back the session token from the response they send...if they don't send you a session ID, you're SOL. If they do send you an session token/session ID, then you need to know what to name it (e.g. PHP uses something like PHPSESSID as the cookie name, but it can be whatever the coders of that domain decided on). Beyond that, you have to be able to set the cookie for THAT domain name (3rd party cookie). This may have mixed results depending on the user's settings--if they block 3rd party cookies--however, since this is a google extension and not a website, maybe it's able to bypass that kind of restriction. I know that FireFox's developer toolbar is able to manipulate cookies for all domains, so it would be a reasonable assumption you would be able to as well.
I've been fumbling around with different client side technologies, like AngularJS, EmberJS, even trying to use straight JQuery and figure out how to use ReactJS with it. That aside, my goal is to build a single page app using json in between the client and a Java Jersey 2 jax-rs back end api.
I have two stumbling blocks right now. Some info though..I am deploying my app as a WAR file in Jetty. My back end is java based. I am using only jquery in the client side as of now.
My main stumbling block is how to handle login, logout and session management. With an rest API and using ajax, I have login working, including it setting a cookie. My concern however is with a single page app, there is just the one index page, and if the user closes the browser, then reopens it to the index page while the cookie/session is still good, the user should be logged in, not see the outside (not logged in) page. I am unsure how to handle this, whether it be a jsp page, index.html with some templating library, etc. With JSP I can insert some scriplet code (against my better judgment). In the old days I'd include a header that would check for request.getSession().getAttribute("user") and if it was there..the user was logged in and using scriplet if() code I'd display a logged in header, instead of the non-logged in header. But I am in the belief there has got to be a better way to do this with todays client side JS frameworks.
The other stumbling block is the navigation and dynamic aspects. For example, when I was messing around with angular js, it was easy enough to use Welcome {{name}} and within the scope replace name with a json response value for the logged in user. In my current situation, I am not exactly sure how to best go about displaying dynamic bits like this with pure jquery other than using some sort of $("#elem-id").innerHtml="..." code within the response success method of an ajax call. As well, I am not quite sure how to handle navigation to different pages. My logged in site will have some drop down menus or links that will replace the content area with different varying amounts of content.
So first, what are some ways in a SPA to handle user sessions, in the case of a page reload, or close/crash browser restart.. to ensure the user is still logged in and direct them to the right page? Second, what sort of templating and routing/navigation options exist that don't require me to put a huge ton of code in my one index.jsp page?
Thank you.
If you're having a REST API as the back end, then you must have implemented oAuth as an authentication mechanism. That is, when your user logs in, using a username and a password, you exchange that data with an authentication token. This authentication token is sent your server with each and every API call and your backend validates this token before servicing the request. Clear so far?
What you could do is, when you obtain the access token, you can also obtain the access token expiration time from the server and store that data in your client side app. In localStorage maybe? And when your user closes the browser and reopens again, you can first check whether such access token is available (and not expired) before asking the user to log in. This should solve your first problem.
Secondly, if you're looking for a lightweight routing option, I recommend director.
I am building a similar application. OAuth is not mandatory. You can have normal sessions etc by hitting the jersey login endpoint and setting a session and a cookie "keepme" with the session if user wants to be persistently logged in. You can then have a jersey AuthFilter for example check if either there is a cookie with a valid session or an active session and keep the user logged in.
Your frontend application should have no say over this, just communicate with the server and if it doesn't get unauthorized access (from the AuthFilter) then continues otherwise it displays the login page.
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.