So, I\'m trying to use tokens with Devise (version 1.0.3 with Rails 2.3.8) to let a user log in, but I\'m not entirely sure where to begin.
http://zyphdesignco.com/b
This was a good starting point for me:
Migration to add authentication_token
:
class AddTokenBasedAuthentication < ActiveRecord::Migration
def change
add_column :users, :authentication_token, :string
add_index :users, :authentication_token, unique: true
end
end
And then in the application controller:
class ApplicationController < ActionController::Base
before_filter :authenticate_user_from_token!
before_action :authenticate_user!, except: <your login GET action>
private
def authenticate_user_from_token!
email = params[:email].presence
user = email && User.find_by(email: email)
sign_in user if user && Devise.secure_compare(user.authentication_token, params[:auth_token])
end
end
And then the link construction is just
www.yoursite.com/?email=the@email.address&auth_token=whatever_auth_token_is_stored_for_that_user
sources: this gist linked to from devise's wiki, & this tutorial (mentioned above)
see this article: http://www.hyperionreactor.net/blog/token-based-authentication-rails-3-and-rails-2
Basically all you need is to append the token to your requests and you're automatically authenticated, i.e. localhost:3000/posts.xml?auth_token=the_token
My understanding is that you can use the tokens to log in or to hit arbitrary pages that need authentication, even with cURL. If you look in config/initializers/devise.rb
, there should be a line that says something like:
config.token_authentication_key = :auth_token
Whatever the name of the token_authentication_key
is should match what you put as the query or form parameter in your request. You used authentication_token
in your example, not sure if you changed devise.rb to match that or not.
If you want to figure out how things are working internally, I would try git clone git://github.com/plataformatec/devise.git
and search for the methods you need clarification of.
Here are some sample cURL requests (I made a custom Users::SessionsController that extends Devise::SessionsController and overrides the create method to handle JSON.)
class Users::SessionsController < Devise::SessionsController
def create
resource = warden.authenticate!(:scope => resource_name, :recall => "#{controller_path}#new")
set_flash_message(:notice, :signed_in) if is_navigational_format?
sign_in(resource_name, resource)
respond_to do |format|
format.html do
respond_with resource, :location => redirect_location(resource_name, resource)
end
format.json do
render :json => { :response => 'ok', :auth_token => current_user.authentication_token }.to_json, :status => :ok
end
end
end
end
And then the cURL requests I gave:
curl -X POST 'http://localhost:3000/users/sign_in.json' -d 'user[email]=example@example.com&user[password]=password'
-> {"response":"ok","auth_token":"ABCDE0123456789"}
curl -L 'http://localhost:3000/profile?auth_token=ABCDE0123456789'
-> got page that I wanted that needs authentication