Hacker News new | past | comments | ask | show | jobs | submit login
HelloJS – Client-side OAuth for JS (adodson.com)
160 points by sidi on Sept 11, 2014 | hide | past | favorite | 56 comments



Hmm, I don't see any mention of security. I can't find the source, but I remember reading that if you wanted to restrict access to certain pages on your site to authenticated users in a single page app it was more secure to do it server side. Security experts feel free to chime in.


> it was more secure to do it server side

It's not it was more secure,it's that it is impossible to secure anything on the client(native or html,by the way) if there is no interaction with a server doing access control somehow. That one reason why old facebook app was downloading HTML instead of having it bundled and just requesting json payloads).

What is a single page app? a single HTML file.How can you secure anything in a single HTML file? there are no "pages", the browser history is just tricked into pushing or poping url states.

You can however decide that an API call will fetch resources like js and css right after a user is logged in,but that's the server doing its job,and the assets would be served either through tokenized temporary URLs , or read on the server's disk , streamed through a server-side language then dumped in the client.

I bet that a majority of SPAs out there dont do that,and sensitive assets are downloadable even when a user isnt logged in.

A non authorized user shouldnt have accessed to these assets,or even endpoint URLs meant for authorized users.But yeah,it means using a proper server-side language and not just serving everything from S3.


Isn't the point of this not to secure some thing, as in "no access", but to sign something and trust it (i.e. a server signs a token and hands it off to another machine/app)?

If your point is "nothing is secure in the browser" then that includes the secured content sent down by a secure server no matter the method.


No idea if HelloJS is a secure client or not, but it's possible. Here's a good resource for how Google offers purely client-side OAuth to API consumers: https://developers.google.com/accounts/docs/OAuth2

I believe this is only possible since OAuth2. One important aspect is that the API provider registers the consumer's key along with their domain, so API requests using that key are only valid coming from that domain.


Probably you mean the FB API that doesn't restrict the redirect URL by default.

Google(+?) requires you to whitelist possible redirect URLs, meaning that it's much more obvious what happens after a redirect. Thus limiting what an attacker may do...


Using client-side script to restrict access is a big no from a security stand point. From what I have read this library is intended to interact with third party services rather than for access. E.g. pulling in photos, contacts etc


Assuming OAuth uses random numbers (don't remember if it does), one issue could be that the RNG of Javascript is not cryptographically secure. I'd be interested to hear the opinion of a security expert too.


I don't see any reason why it would need random numbers for OAuth 2.0. Part of the reasoning that went into the OAuth 2.0 spec is that not all applications might have access to encryption, so encryption should only be used at the protocol level (i.e. HTTPS).

As it requires an "OAuth proxy" for OAuth 1.0a and some implementations of OAuth 2.0, it seems that it offloads the crypto (and secret API key) to that proxy.


This statement is incorrect, Math.random is (generally) not a CSPRNG, but there is window.crypto.getRandomValues in modern browsers.


From my understanding this is also the case ie. don't do OAuth client (end-user/browser) side.


If the client passes the server a token which the server can verify against the third-party service providing the login, I don't see a reason not to trust the client. I'm very interested to hear what kind of security problems this could bring - if they can be mitigated, using this library would be very convenient for some projects.


I didn't look at this in detail, but this appears to also be using refresh tokens. Getting clarity on refresh tokens is a bit tough, but they are intended to allow one to request a new access token when the access token expires. I don't think refresh tokens are intended to be stored client-side as they are with this. If a refresh token is compromised, it can be used to request an access token for the user.


HelloJS is great. I've used it in my last project. It just works. It's well tested, and well documented. There's very little option twiddling required. It just worked seemlessly when I was trying to setup Twitter, Google, LinkedIn and Facebook OAuth logins.


Nice endorsement


This is great, perfect for little consumer web apps. I am so happy about this, becuase we (my dev buddies) have just had an idea for a little social game that would be great if ported onto the web. I think I have just solved our simplistic user auth needs by reading this article.

Thanks for sharing.


How does this get away with not using the client secret? I thought OAuth 2.0 always required a three-way handshake (client is sent to provider, provider sends client back to service, service exchanges grant token with the provider).

Does this mean in Facebook, Google etc the grant token and the access token are identical?


This is a terrible idea that is full of security holes! If you can call having paper-thin pseudo security a hole.


Security holes such as? Please elaborate.


From what I gather you are leaving the api_tokens for the services in local memory. This means that the user or anyone else that can get there hands on the token can act on the service providers api masquerading as your application.


Is not a session cookie the same thing? I'd argue if your tokens only live in memory they can be more secure. It also depends how long your tokens live or how many requests they are good for. No?


Usually the token kept in memory is one distributed by the application and is not that which the services send back. This allows greater restriction on actions and make it far easier to revoke effectively


The token in this case is for the local user, that you know, logged into the service in question... How is it insecure for my browser, with me in front of it, to be logged into facebook? I mean, yes, if you're using anything other than a session cookie or sessionStorage, there's risk from other users on the system... but with an SPA, without any hard storage, it's no less secure than using that site/app.


Usually the token kept in memory is one distributed by the application and is not that which the services send back.

What is application in that sentence? The API?

Isn't that what this lib does?

A client-side Javascript SDK for authenticating with OAuth2 web services and querying their REST API's.

- I assume the API issues the token - This lib receives it and uses it for subsequent calls - The token is destroyed when browser session is closed.


I am referring to the application you are writing


It only has the `client_id` on the page. The `client_secret` is not disclosed to the user, although using it apparently requires using the "OAuth proxy".

I'm baffled this actually works. The entire idea is that the `client_id` can be disclosed to the user (via the login redirect) because the `client_secret` is required to verify the application's identity.


Well, assuming that the front-end app is served through SSL (avoid MITM), the only other possible hole I see is physical access to the machine while the browser tab is open, no? Can other browser tabs, malware or browser plugins access memory while the app is running?


Session store is a good place for these, purges on browser close. Or logout, and those api_tokens are no longer valid. To me, lightweight, throwaway tokens seems exactly the purpose of oAuth.


It really depends, it will purge on browser close yes but it still allows access that make not have been intended by your application for use by others also the refresh token may also be stored. The danger is in someone getting this token from an active session and using it outside of its intended parameters not the normal use case.


Not doubting you, but I would love to see the methods to make this happen. Is your concern from a 3rd party script included on the page?

From my experience memory is safe between origins in the same way cookies are. And it is the dev's responsibility to not do something stupid with the token like window.FacebookToken = OAuthToken;. But that holds for traditional session cookies as well.


Very interesting project! Can you explain what some of the differences are between this library and PassportJS?


Passport is sever and side meant for use with nodejs [1]. This is client side for use with bower [2].

[1] http://nodejs.org/ [2] http://bower.io/


PassportJS = NodeJS authentication, designed for single sign-on.

HelloJS = Browser + Phonegap authentication and API request handling designed to interact with thirdparty services from the client app.


Firebase simple login does provide similar functionalities right ?


Could you explain why I should favor client-side auth over server-side auth, especially if I want to do some action on behalf of the user, like generating word-clouds of their posts, etc. And what makes helloJS different from oauth.io, which has open-sourced their server?


One example I can think of would be a mail reader application, that ties the storage of their application to say DropBox. You can have the user authenticate their dropbox, so their account details won't even need to be stored on the server. This would work well for a chrome/firefox application for that matter.

I can think of a few other systems where it would be useful, but in general an application interface (including offline support) comes to mind here.


may be if you change view on what and where software should be doing it might click together. i.e. for example all real work happens on client and client app offloads only storage of computed data to your servers via separate authentication. this is shift of paradigm back again to "desktopish apps", but still quite viable in certain situations.


And if you want to offer a desktop app, a web-based app, and native ios, android, fire, and tinzen apps, then all that client code is duplicated. And good luck if you need to update them all.


Thanks for sharing my project HelloJS


Hi, thanks for putting this together and releasing it. I'd like to use it on our corporate intranet, but we use the OAuth2 implicit flow with JSON web tokens. Does hello.js support this use case?


I couldn't find any examples of JSON Web Token in the client. But if the security model supports it then i'd like to entertain the idea.


Hi... thanks for writing this. As a newb on these sorts of issues, I have some questions:

1. So this is 100% client side... Why do I see "npm" in the instructions? Isn't that connected to nodejs? What if I'm writing a java web server app, will this still work, or does it need to talk to a nodejs server somehow?

2. I take it none of this hits a third party server (i.e. your server)?

3. How do I get the user's info obtained via authentication (gmail address, etc) to my server, in a way that is secure, if this is all client & browser based?


1. NPM is just an easy way to install it, you can also use bower or just download the source and minified packages.

2. I see no reason why it would.

3. It's all client based regardless of how you do it, it just adds cookies. If you want to get the information server side just get it server side (PHP example https://github.com/thephpleague/oauth2-client) there is no need to get it client side if you need it server side with a server side library (thus why NPM is shown as node is server side).


Use node for bundling+minification.

Its on npm for convenience. I also hope to make it compatible with CommonJs and have components of it work through the server.

Not all services support server-less authentication otherwise known as Implicit OAuth2. As such, i've put a proxy service up on Heroku. Read up at http://adodson.com/hello.js/#oauth-proxy


1. NPM is used for installing bower [1], a package manager for client side libraries.

[1] http://bower.io/


Once you're authenticated in a client web page, lets say you want to perform data storage on your own server using this authenticated user as validation. How would your server validate the user's login is valid to accept user actions?


Make a server-to-server call using the token to check its validity.

There's more comments on this subject here https://github.com/MrSwitch/hello.js/issues/22


I really like adodson's web game. Check out http://adodson.com/#escape for browser MineField & Flood It.


Looks great. It's such a pain to write separate authentication / profile retrieval logic for each service.


This looks pretty awesome. Could it be used for importing email contacts from gmail/yahoo/live etc.?


@ishi take a look at this example http://adodson.com/hello.js/demos/friends.html


This looks amazing. Are you planning on adding any other services?


Yes, but its a pretty arduous task digesting and implementing API docs. That pain was the impetus to standardize them into the HelloJS library.


Client-side authentication. In javascript.

What could possibly go wrong? ;)


Oh my god the kerning on that font.


Point and space taken. Now it is readable - and I rather dread the consequences.


I t o t a l l y a g r e e .




Join us for AI Startup School this June 16-17 in San Francisco!

Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: