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?
How our “test” project structure will be:
test +--- 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 very basic app/app.js:
The main page on the browser:
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:
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! :)