devise中如何使用auth_token認證 與 RubyChina api認證的區別

hexudong08發表於2012-07-13
1.  修改配置檔案  config/initializers/devise.rb

   config.token_authentication_key = :auth_token
   
2. 修改controller action

  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 

3, 可以使用如下的命令測試

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
  

devise 提供的auth token 方式不是很合適,需要修改devise.rb配置檔案,與web認證衝突
還是RubyChina實現的比較好一點
   
Ruby-China的程式碼中如何實現tokenauthentication登入
1, 登入的時候生成private_token程式碼

  # 使用者金鑰,用於客戶端驗證
  field :private_token

  # 重新生成 Private Token
  def update_private_token
    random_key = "#{SecureRandom.hex(10)}:#{self.id}"
    self.update_attribute(:private_token, random_key)
  end 


2, 在客戶端登入的時候,返回 private_token

  def create
    resource = warden.authenticate!(:scope => resource_name, :recall => "#{controller_path}#new")
    set_flash_message(:notice:signed_inif is_navigational_format?
    sign_in(resource_name, resource)
    respond_to do |format|
      format.html { redirect_to after_sign_in_path_for(resource) }
      format.json { render :status => '201':json => resource.as_json(:only => [:login:email:private_token]) }
    end 
  end 

3, 可以使用如下命令測試
curl -X POST 'http://ruby-china.org/account/sign_in.json' -d "user[login]=xxxx&user[password]=xxxxxx"

4, 如何在下次介面定義中使用?
      # file path: lib/api.rb
      #
      # Post a new topic
      # require authentication
      # params:
      #   title
      #   body
      #   node_id
      post do
        authenticate!
        @topic = current_user.topics.new(:title => params[:title], :body => params[:body])
        @topic.node_id = params[:node_id]
        @topic.save!
        #TODO error handling
      end 
5, authenticate!的原始碼【在lib/api/helper.rb檔案中】
    # user helpers
    def current_user
      @current_user ||= User.where(:private_token => params[:token] || '').first
    end 

    def authenticate!
      error!({ "error" => "401 Unauthorized" }, 401unless current_user
    end 
RubyChina沒有使用Devise預設的認證碼,定義了一套新的認證機制, 結合 Grape 做介面,與 web層
    
  

相關文章