oAuth2 authentication on a JavaScript app - javascript

I'm planning to refactor a legacy Rails 2 app by splitting the logic into a RESTful API, and the view into a separate Javascript client. The API itself will be protected by oAuth2. This is basically the second option explained on this question:
Separate REST JSON API server and client?
There's a lot of questions out there concerning the security of using oAuth with a JS app, the main concern seems to be that storing the access token on the client is a bad idea since it acts as a password and someone that has physical access to the computer can hijack the user's identity. A possible solution I've read is to expire the access token every 1h or so and use the refresh token stored on Yahoo's YQL to request a new token when necessary. This doesn't looks to me like a good solution since at the end you'll need again a token to access the YQL service.
But at the end, aren't we facing the same problem as when using persistent sessions? I mean, AFAIK, the common method to keep the session alive across browser opening/closing (when you tick "remember me") is to generate a token associated to a user and store it both on the DB and on a long-living cookie. So again, anyone with access to this cookie has the "key" to your session. AFAIK this is the method all the "big guys" use.
I am right? And if I am, aren't we worrying too much about something that we cannot control at all? Of course I'm talking about those applications where an intrusion is not too harmful for the user like social networks, blogs, forums, etc.

Related

I want to limit the total number of articles read on my webpage by a user, without signup, like how medium does

I don't have any idea how to implement this. After a bit of search I found out that medium keeps track of the browser and not the user, what is mean is you can access three free articles from each new browser on the same machine (if I am wrong do point it out). I am using React and Firebase for my website.
Edit: I was thinking along the lines of getting some kind of id which is unique to a browser. As cookies and local storage can always be bypassed.
I don't know if it's a clean way to do it but you can associate an IP to an unique counter. Or with a cookie but he can bypass that by cleaning the cookies
The answer would tightly depend on your application setup and especially on the service backing your front store.
If you are using a self-backed backend, for example a nodejs - express based server, within your route middleware you can access the remote address from the req.connection.remoteAddress request property along with the user-agent req.header('User-Agent') and forward these to your datastore being Firebase in this case.
If you are deploying your application to Google Cloud Function, you can then access the remote peer address using the fastly-client-ip request header and still forward this to your storage system.
Use javascript and implement a system that uses a cookie or local-storage to verify how many articles are read on your website.
On most of these websites however you are still able to bypass this limit by clearing the cache or using a incognito window.
To also limit these scenarios you can use a cookie in combination with an IP address, which has its own drawbacks, especially in corporate environments, and mobile connections where IP addresses are heavily shared or changed. Depending on your situation this may matter or not.

Is it a secure way to handle returning user in ember?

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.

How to use JWT for a proxy server written using Node.js?

This is absolutely a newbie question & I am Node.js beginner.
I am not sure, this is right place to ask this question. But I may need idea from this large community. So let me explain what I am trying to do.
Server Configurations:
Node.js - 4.0.0
Hapi.js - 10.0.0
Redis
Scenario:
I am writing a proxy server in nodejs using hapijs. My Backend is ATG based e-commerce website and my api's are going to be consumed by web browser, mobile app etc..
We planned not to send the cookies sent by ATG to both browser and mobile.
So to maintain sessions and cookies from ATG,this is how we done POC.
First We planned without considering storing the anonymous user cookies returned from ATG. So we have done two POC's.
(Many of us know, what anonymous cookie is,any way let me explain that, if I put that one word -- Guest Checkout. There are many ways to accomplish this. But my Commerce Backend is implemented like this, When we go to website, you add items to cart and checkout that items without logging in right ? This what happens on background whenever we add the items they are only stored in your browser cookie,it not stored in persistent database, in any case user wants to login/signup to the account that cookie is retrieved from the browser and stored in database (basically that anonymous cart is transferred to logged in user.))
POC-1 (Not Considering Guest Checkout):
To access my api, user must be logged-in, after the successful login, We generate a rand-token and store it in Redis db associated with the cookies sent from the ATG for logged-in user and set ttl for 1 hour and return that token to the client
Now whenever they invoke any of api methods, they should send the token in the authorization header, I will check for token validity and expand the ttl once again for 1 hour and retrieve the cookies associated with that token, set that cookies in ATG request options and make a request.
3.On logout, I will clear the cookie and delete the token.
I have successfully implemented JWT fot this scenario, by generating a JWT token with user logged-in information in jwt payload. Used hapi-jwt-auth2.
POC-2 (With Maintaining Guest Cookies),
My API Will have endpoint /auth/generatesession, which in turn will return a 64 byte random token (we are using rand-token npm module for that) which will expire in 24 hours.
All the methods needs that access token passed back to me in authorization header and I will extend that token ttl to 24 hours.
Now they can invoke any api methods, like addtocart or something, even after adding items to cart , suddenly they want to login or something I can use their guest session cookie and transfer that cart to persistent database after successful login.
Questions:
Should I use JWT for the second scenario? If so,
How can I implement JWT for the Second Scenario? (Coz, don't know about who is the user?)
Does anyone think this is good idea for writing proxy server like this?
How can streamline session expiry of this token with ATG session Expiry?
Does anyone of using Node.js like this? How does it scale ?
If anyone care to give me an idea how to write this proxy server, it will be much helpful for me.
I Apologize, if this is too long question, just my way of explaining things.
Thanks in advance.
Sure, why not?
You don't necessarily need a user. A JWT stores arbitrary data, the username can be blank or anonymous. If a user logs it, and provides a token associated with a guest cart, then it can be assumed that that user is allowed to claim the contents of that cart, and the anonymous cart can be destroyed.
Sure, this is quite common (disclaimer: I've worked on something very much the same as you).
TTL is reasonable, but I have no idea what ATG is or how it handles it.
Yes. It scales very well as long as you ensure your servers are stateless, and that you manage all your state through something like Redis.
Too broad of a question, I would just use Express + Redis/Mongo/Postgres.

Cross Domain Authentication with EasyXDM

I am trying to do a login like Google does, which includes a cross-domain-authentication. When loggin into google.com you are automaticly logged in for different domains like youtube.com. For me it looks like:
you enter credentials at accounts.google.com
Google sends a request via AJAX to check them
if they are correct, it 1. sets a cookie and 2. does requests to the other domains like youtube and sends some identifiers (SID or token?) and sets the cookies for those domains as well
after all other domains also have the cookie in place Google redirects you back where you came from
I was researching a lot and it seems like easyXDM (http://easyxdm.net/wp/) is a good solution for this (do you think it is?). But I am not sure how to do the cross-domain-authentication. When the user logs in correctly, should i just do requests to the other domains and pass the SID and create cookie on the domains? Or is it not secure? Or should I create a token for the user after loggin in and store it in my DB. Then send the token with to all the domains to authenticate him and then delete the token?
Some other stuff i found was a solution via iframes in iframes.. also Googles analytics.js (https://developers.google.com/analytics/devguides/collection/analyticsjs/cross-domain) looked exciting... but i saw it's even integreated in easyXDM.
I hope some if you guys are having experience with that stuff. I am curious to read what you think :) gerti
What you want is OAuth2 (this is the protocol you're referring to -- what Google login does).
If you're looking for a simple solution, you might want to try using something like Stormpath + IDsite. It's a free API service you can sign up for / use.
Basically, they'll host a domain for you where you redirect your users when you want them to create an account or log in. They'll then handle all the authentication / authorization (across domains), and send you back an authenticated user with a JSON web token (JWT).
Stormpath has a bunch of libraries for a variety of programming languages, you can get started here: https://docs.stormpath.com/home/
The other solutions people typically go with require quite a bit of time / effort to get running. I've actually helped build quite a few of the Stormpath libraries (in Node / Python), so I'm pretty familiar with it -- you really can't beat it in terms of simplicity.

Where is best place to store authorization data when I use Backbone and AMD modules?

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.

Categories

Resources