Reputation: 786
I'm using Devise in a Rails 3 app for user authentication. This app also serves API responses to a mobile application. I read that Devise removed their token authentication feature for various reasons, and I've implemented it in my application based on this gist: https://gist.github.com/josevalim/fb706b1e933ef01e4fb6
class ApplicationController < ActionController::Base
protect_from_forgery
# before_filter :authenticate_user_from_token!
before_filter :authenticate_user! # Devise's default auth
private
def authenticate_user_from_token!
user_email = params[:user_email].presence
user = user_email && User.find_by_email(user_email)
if user && Devise.secure_compare(user.authentication_token, params[:user_token])
sign_in user, store: false
end
end
end
Here's the first part of the controller in charge of API responses:
class ApiController < ApplicationController
before_filter :cors_preflight_check
after_filter :cors_set_access_control_headers
before_filter :authenticate_user_from_token!
# For all responses in this controller, return the CORS access control headers.
def cors_set_access_control_headers
headers['Access-Control-Allow-Origin'] = '*'
headers['Access-Control-Allow-Methods'] = 'POST, GET, PUT, OPTIONS'
headers['Access-Control-Max-Age'] = "1728000"
end
# If this is a preflight OPTIONS request, then short-circuit the
# request, return only the necessary headers and return an empty
# text/plain.
def cors_preflight_check
if request.method == :options
headers['Access-Control-Allow-Origin'] = '*'
headers['Access-Control-Allow-Methods'] = 'POST, GET, PUT, OPTIONS'
headers['Access-Control-Allow-Headers'] = 'X-Requested-With, X-Prototype-Version'
headers['Access-Control-Max-Age'] = '1728000'
render :text => '', :content_type => 'text/plain'
end
end
... (response methods)
And my routes for the HTTP requests:
scope(:path => '/api/v1.0/') do
match '/candidates' => "api#candidates"
match '/districts' => "api#districts"
match '/articles' => "api#articles"
match '/candidates/:id' => "api#candidate"
match '/districts/:id' => "api#district"
match '/articles/:id' => "api#article"
match '/search' => "api#search"
end
How do I create routes for logging in via API (the user submits a request with an email and password and receives a token)?
Upvotes: 1
Views: 1688
Reputation: 3754
What do you mean with "How do I create routes"? Probably you want to create a class with a method to check email and password that returns the token, e.g.
class Tokens < ApplicationController
def create
@user = User.find_by_email(params[:email])
# Check for password too!!
if @user && @user.valid_password?(params[:password])
render status: 200, json: { token: @user.authentication_token }
else
render status: 411, json: { error: "Error message..." }
end
end
end
And finally add to your routes:
post '/tokens' => "tokens#create"
Hope it helps.
Upvotes: 1