Adam Albrecht

ruby & javascript developer in columbus, ohio.

Authentication with JSON Web Tokens using Rails and React / Flux

In a previous post, I went over how to add authentication to your Rails + Angular app using JSON Web Tokens (JWT). This time, I’ll do the same, but using the React ecosystem. But even if you’re using another front-end framework (Angular, Ember, Backbone), this post will be helpful because it fixes some issues with the previous server-side code that broke due to a change in the jwt gem.

Read More

How to Replace the Angular Stack with React plus a few NPM modules

As you can tell from the content of my blog posts, I’ve been practicing and preaching Angular.js for quite some time now. It is an extremely productive web framework that felt like a big step forward from my days doing jQuery “sprinkles” and then Backbone.

But then recently, I started playing with Facebook’s React framework. And while I’m still not quite as productive as I was with Angular, I absolutely love the code that I’m writing. And on top of that, it has opened my eyes to a whole new paradigm for creating user interfaces.

Read More

Authenticating your Angular / Rails App with JSON Web Tokens

UPDATE: There have been some changes in the JWT Gem that make some of the below not work exactly right (it’ll still be about 90% the same). Specifically, they added expiration support. See my post on the same topic, but using React.js. The server side code in this post will work just as well with Angular.

Overview

I’m a big proponent of rolling your own authentication solution, especially if you’re only doing simple username/password based logins (as opposed to logging in via an OAuth provider). I’ve tried to use Devise on a number of Rails apps, but I always end up ripping it out. It’s not because Devise is a bad gem, but because it always takes me more time to customize it to my liking than it does to just write everything myself. And the flexibility of a custom solution almost always comes in handy down the road. I have generally implemented it the same way that Ryan Bates does in this Railscasts episode.

But now that most of my greenfield projects are single page javascript apps, authentication has become slightly more complicated. While you can certainly continue doing traditional authentication with cookies and server-rendered views, my preference is to use a token-based approach. This has a number of benefits:

  • The same authentication API can be used by all types of clients (web app, mobile app, etc).
  • It is stateless, so the web server does not have to keep track of session information, which is good for scaling.
  • Protected against CSRF (cross-site request forgery) attacks
  • All of your views are rendered by the client, rather than a mix of server and client rendered views.

A relatively new standard for accomplishing this is JSON Web Tokens (abbreviated to JWT). I won’t dig into the details because there are plenty of good resources, but JWT is a way of digitally signing data to be transferred between two parties. The data is represented as an encoded JSON object. In a nutshell, these tokens are passed to the client upon successful authentication and then subsequently used in every HTTP request in order to verify the identity of the client.

Read More

Authorization with Angular.js and UI-Router

While working on an angular.js application recently, I found myself needing some form of authorization logic (not to be confused with authentication / login). I needed to restrict content in my app based on a user’s role as well as some other factors. At first, I created a single AuthService service that dealt with login, authorization, and session management. But this felt messy and violated the Single Responsibility Principle, so I decided to make something cleaner. My goal was for the API to look something like this:

(Warning: lots of coffeescript ahead!)

LoginService.login(email, password).then((u) ->
  Session.setCurrentUser(u)
)
# ... Elsewhere ....
user = Session.getCurrentUser()
authorizer = new Authorizer(user)
authorizer.canAccess(APP_PERMISSIONS.viewAdminSettings) # returns a boolean

By doing it this way, I was fairly sure I could split my formerly monolithic AuthService into 3 separate services that had no dependencies on one another. I won’t go too detailed into the login and session services because they are fairly straight forward. LoginService has one method that simply makes an HTTP request with a username and password and, if successful, returns the user object. Session is a singleton service that, given a user, can create or destroy the current session. But my solution to Authorization was fairly interesting, so I thought I’d share.

Read More

Building your Angular app with Gulp.js

As my work has transitioned from traditional web apps to thick-client Javascript apps (primarily using Angular), Grunt has become essential in my workflow. Grunt is a nice tool and it gets the job done. But there was always something I didn’t like about it that I couldn’t quite articulate until I discovered Gulp.js. Whereas in Grunt, you create a json configuration file, Gulp is just a script. It’s code. And it really fits my programmer brain better. In this post, I’ll convert a basic Gruntfile that compiles and minifies Coffeescript into Gulp.

Read More