Settings

Theme

Show HN: Satellizer – Authentication for AngularJS

github.com

221 points by sahat 12 years ago · 37 comments

Reader

filearts 12 years ago

This is a very nice solution and API for the front-end. It took me a couple part-time months to put together a similar (not modularized) solution for a rewrite of Plunker. There is quite a bit of juggling of information to do to pass around the appropriate information between client, server and auth providers that seems to have been nicely abstracted.

There were three major challenges for me in my implementation and I'm wondering how these could be addressed with Satellizer:

1. Anonymous content creation that can be attributed to a user upon sign-up or sign-in. On Plunker, anonymous users can create 'plunks' that will then attributed to them if they decide to register. This is important to allow streamlined user acquisition.

2. Account merging when someone accidentally creates two different user accounts with different social identities. This gets weird when anonymous content creation is involved since someone could create content while signed out and would need all that content re-attributed when they sign in.

3. Multi-provider authentication. In Plunker, certain features will only be available if the user has linked (for example) Dropbox. This means consumers of the api need to be able to add / remove social identities to / from users.

Hope to hear how you might attack these problems with something like Satellizer (or other people's approaches that have worked).

  • ovidiup 12 years ago

    The account merging part is something your server should handle.

    In my app I maintain a users table that has columns (google_account_id, facebook_account_id, twitter_account_id, etc), pointing to individual rows in a separate accounts tables (e.g. google_accounts, facebook_accounts, twitter_accounts etc). When a user adds an existing account_id, I take care of merging the two different users rows, populating appropriately the account_id in one of the rows, then deleting the extraneous users row. I also migrate the existing data referring to the to-be-deleted user row to the one I plan on keeping.

    • filearts 12 years ago

      Thanks for the reply. That is the approach I take. Users have one or more identities which seems to be the logical way of handling this regardless of the physical structure used to store the association.

      While you gloss over it a bit, the 'migrate the existing data' part is a challenge of its own because it means that suddenly the auth component needs to either know every place where a user<->content association is made or you need some sort of queue set up to publish user merges to all parts of the app in a reliable and durable way so that they can process the migration themselves.

      I would say that this is also a UI concern and therefore something that a service like this would need to handle because it should _not happen automatically_. When a user conflict is detected, the user should be able to make a decision via appropriate UI. We would not want two accounts being merged simply because of some degenerate case where someone logged into their account on a borrowed computer.

    • jgrowl 12 years ago

      You could create an identities table which consists of a provider and a uid where Users have many identities. Something similar to this:

      https://github.com/intridea/omniauth/wiki/Managing-Multiple-...

      Use what works for you obviously, but this would have the benefit of scaling easier if you end up ever needing to support additional providers.

lynndylanhurley 12 years ago

I built something similar that's gained a bit of traction:

https://github.com/lynndylanhurley/ng-token-auth

ng-token-auth comes with a Rails gem, and it's configurable to work with almost any API.

eric_bullington 12 years ago

This is a very, very nice project -- almost enough to pull me back from ReactJS back to AngularJS. Almost.

One question: they say it can be adapted to any Oauth1 or 2 provider, but doesn't the Oauth 2 provider have to support the Implicit Flow for this type of client-side app to work?

If so, is it true that Github doesn't support Implicit flow? (this is what I've read, and I've not found much on the web otherwise about what exact oauth flows Github supports)

  • sahatOP 12 years ago

    Satellizer gives you an illusion that you're doing an implicit grant flow by opening a popup and then magically you are signed-in. But authorization process is handled on the server: https://github.com/sahat/satellizer/blob/master/examples/ser...

    I just implemented a GitHub sign-in and it took me only 8 minutes because on the server it was mostly copy-&-paste of the Facebook sign-in and on the client it's just:

      $authProvider.oauth2({
        name: 'github',
        clientId: 'xxxxxx',
        url: '/auth/github',
        authorizationEndpoint: 'https://github.com/login/oauth/authorize',
        redirectUri: window.location.origin
      });
    
    Thank you. I like React too so perhaps someone could implement something like Satellizer that integrates with React.
    • eric_bullington 12 years ago

      Thanks for the explanation.

      >I like React too so perhaps someone could implement something like Satellizer that integrates with React.

      Indeed. And such a project could still make use of the server code of Satellizer, I'd imagine.

jgrowl 12 years ago

This looks neat!

It looks like there is a good amount of config for handling different providers. Have you check out OAuth.io and its opensource core oauthd?:

https://github.com/oauth-io/oauthd

https://github.com/oauth-io/oauth-js

It's a simple node app and js sdk that lets you handle providers in a standardized way.

I created a ruby omniauth strategy that simplifies multiple provider support on the backend. A similar approach could be applied to any language:

https://github.com/jgrowl/omniauth-oauthio

JonnieCache 12 years ago

I really wish this had been around a month ago. I guess I learned a lot about angular by building it myself.

evilsnake 12 years ago

I may be paranoid, but is there any security concern about doing authentification on the frontend ? Wouldn't the user be able to see exactly what is going on and intercept some sensitive information ?

skybrian 12 years ago

It seems like a nice start. Who will do the security review?

oatmealsnap 12 years ago

I tried implementing a token-based authentication system, and it worked fine for a while. Then we added a subdomain (login.mysite.com) for registering, and it all went to shit. They don't share the same localStorage, so keeping the tokens in sync can be tough.

  • jnbiche 12 years ago

    Does it have to be a subdomain? Few people pay attention to whether they're logging in to login.mysite.com or mysite.com/login The few times I've tried to guess a web page's login address, I've tried both a login subdomain and a login directory.

MrBuddyCasino 12 years ago

Not working for me - got a 404 for http://rawgit.com/sahat/satellizer/master/lib/satellizer.js

  • gt565k 12 years ago

    I was wondering why the demo site wasn't working.. it 404'd on the js file.

zo1 12 years ago

How easy is this to use without AngularJS? Additionally, if not, does anyone know of any alternative JS (or perhaps Python) libraries for what Satellizer does?

fudged71 12 years ago

I tried logging in with Twitter and wasn't redirected back to your app, so I wasn't able to log in. (Latest Chrome on OSX)

pingburg 12 years ago

This is very helpful. How about handling validation and errors (e.g. unique account)?

  • filearts 12 years ago

    It seems like a lot of this heavy lifting is left to api / backend implementors and is not explicitly addressed. I don't think that is a short-coming of the module but perhaps some additional documentation on best practices could be helpful.

    • sahatOP 12 years ago

      @pingburg @filearts You are right, unique account validation and error handling belong to the server. What Satellizer can do is catch an error through the $auth.authenticate().catch() promise and display it to the user. I will definitely update the documention very soon. The README of https://github.com/sahat/hackathon-starter could fit on a screen when I first posted it on Hacker News earlier this year; it is now 1300+ lines long.

nobullet 12 years ago

I wonder: why Java and Spring? Do you consider other Java implementations?

  • sahatOP 12 years ago

    I have considered Play Framework and Dropwizard. Play it seems is better suited for Scala language and I don't know much about real-world usage of Dropwizard. Between Struts and Spring, Spring seems to have a more active community. I haven't done anything with the Java example yet so Spring can easily swapped for something else if you think that other framework is better. I am not a Java developer so I need someone's help on this one.

kclay 12 years ago

Were was this a month ago. Had to do this for Play!, great work.

datasmash 12 years ago

Wow, this is pretty handy. Awesome work!

motyar 12 years ago

Good work +1

bmelton 12 years ago

So, how would this work if I'm using Python-Social-Auth as the provider as an interface to Django?

Most sites implementing social auth don't do it in the client directly, but as an interface to the oauth and then just trusting that authentication as canon, while simultaneously invoking a non-oAuth login() method at the tail end of the oAuth login. Not sure how this relates directly.

That said, this is a FANtastic, and very necessary module, and hopefully it covers what I think is the most common use pattern.

  • sahatOP 12 years ago

    Satellizer is designed to be used without auth libraries such as Passport (Node), OmniAuth (Ruby). On Python-side all you need is the requests library. It is so by design to avoid relying on third-party libraries. Additionally, if I were to implement it with a server-side auth library there is no choice but to use full page redirects, i.e redirect to Facebook, authorize the app, redirect back to the app.

    • bmelton 12 years ago

      Thanks a million for the response. I think that's appropriate, but I've found sort of a hybrid solution that I was already working on before satellizer came out, incorporating a fix that looks vaguely like this:

      https://github.com/omab/python-social-auth/issues/68

      That said, I'm working through piecing that together with satellizer, and I wanted to give you a huge thanks for including the server examples in so many languages, which ought to be of use.

Keyboard Shortcuts

j
Next item
k
Previous item
o / Enter
Open selected item
?
Show this help
Esc
Close modal / clear selection