Rails and AngularJS: Authentication with Devise

So you have an AngularJS application running on a domain (https://myfabulousapp.com) and the Rails API running on another domain (https://api.myfabulousapp.com). All works good, but you now want to implement authentication using Devise.

How do you do this?

Before start:

How our “test” project structure will be:

  +--- api (Rails, running on localhost:3000)
  +--- app (Angular, running on localhost:3001)
        +--- index.html
        +--- app.js
        +--- bower_components/
        +--- views
               +--- home.html

Let’s create our “test” project with these commands:

# create aplication folder
mkdir test
cd test

# create backend (api, Rails)
rails new api --api
cd api

# install Devise
gem 'devise' >> Gemfile
bundle install
rails generate devise:install
rails generate devise user
rake db:migrate

# start backend server
rails s

Open another terminal window:

# create frontend folder (app, Angular)
cd test
mkdir app
cd app

# install Angular and the router library
bower install angular --save
bower install angular-ui-router --save

# install a minimalist html webserver
# gem install adsf

# start frontend server
adsf -p 3001

Our app/index.html:

Our very basic app/app.js:

The main page on the browser:

1. Install rack-cors gem:

2. Allow Angular to access Rails:

DO NOT add ":options".

If you do that, you won't be able to destroy sessions, because AngularJS will replace "delete" with "options" when communicating with another domain (and Devise doesn't recognize the "option" verb as a "delete")

Don't forget to restart the server!!!

2.5. If Rails "--api", enable Sessions:

3. Install angular_devise library on your Angular app:

4. Configure Angular:

A) Add Devise module to the app:

B) Set $http to always provide credentials:

C) Set Rails API URLs (change api_url to your actual API location):

Or a more extensive example:

5. Remove the CSRF protection from Rails (I know, I know...)

Comment (or delete) the protect_from_forgery line. Also, add a :json to the respond_to, so it will respond to JSON calls.

After testing your app and know it is working, you can look for a better solution to deal with CSRF, like use this angular_rails_csrf gem (which hasn't worked for me, but you may have more luck - see my tries here).

6. After a refresh, get the session back

That's all! :)

Close Menu