欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

使用Rails&Devise为移动设备建立一个简单的API登陆服务 博客分类: Web

程序员文章站 2024-02-21 13:16:40
...

使用Rails&Devise为移动设备建立一个简单的API登陆服务

使用的工具与源代码

Devise (https://github.com/plataformatec/devise)

Rails 4  (https://github.com/rails/rails)

Ruby-china 源代码 (https://github.com/ruby-china/ruby-china)

 

流程

利用API进行登陆,获取授权代码信息,使用授权代码信息与需要进行验证的API进行交互

 

配置Devise

增加authentication_token字段

假如应用已经初始化过了devise的user表,那么就需要额外利用rails生成一个新的数据迁移脚本

 

#rails g migration addAuthTokenToUser
class AddAuthTokenToUser < ActiveRecord::Migration
  def change
      change_table :users do |t|
          t.string :authentication_token
      end
      add_index  :users, :authentication_token, :unique => true
  end
end

 

 

编辑models/user.rb,增加相应的devise功能 :token_authenticatable

 

  devise :database_authenticatable, :registerable,
         :recoverable, :rememberable, :trackable, :validatable,:token_authenticatable

 

 

 

建立控制器与路由

我们需要建立一个名为Token的控制器作为登陆/获取授权代码的入口

则先配置相应的路由,在config/routes.rb文件中增加以下代码

 

#config/routes.rb  
namespace :api do
    namespace :v1  do
      resources :tokens,:only => [:create, :destroy]
      resources :products
    end
 end

 然后新建相应的tokens_controller.rb文件,首先先写一个登陆登陆的方法

 

 

#controllers/api/v1/tokens_controller.rb
class Api::V1::TokensController  < ApplicationController

    skip_before_filter :verify_authenticity_token
    respond_to :json
    
    def create      
      email = params[:email]
      password = params[:password]
       
       if email.nil? or password.nil?
         render :status=>400,:json=>{:message=>"Password&Username cannot be blank"}
       return
       end

       @user=User.find_by_email(email.downcase)
        
      @user=User.find_by_email(email.downcase)
 
      if @user.nil?
         render :status=>401, :json=>{:message=>"Invalid email or passoword."}
        return
      end

       if not @user.valid_password?(password)
         render :status=>401, :json=>{:message=>"Invalid email or password."}
       else
         render :status=>200, :json=> {:token=>@user.authentication_token}
       end
    end

end

 

 

这样相当于建立一个api路径-localhost:3000/api/v1/tokens.json,顺便说明跳过的这个前置验证器

 

skip_before_filter :verify_authenticity_token

 因为rails默认会为所有Post的form增加一个提交表单用的验证代码,防止站外提交post方法。(《企业应用架构》一书里好似关于这种设计的具体说明)。但是通过手机提交post方法无法获取这段验证代码,所以api部分全部需要忽略这个内建的验证期。

 

 

测试

使用curl测试是不是正常工作

 

 curl -XPOST -d ''  localhost:3000/api/v1/tokens.json

 因为没有输入用户名和密码应该返回一个我们设置的错误信息,{"message":"The request must contain the user email and password."}

 

 

 

如果输入正确的用和用户用户名如

 

 curl -XPOST -d  "email=test@gmail.com&password=123456"  localhost:3000/api/v1/tokens.json 

  则会收到一个正确的应答,并且获取相应用户的authentication_token栏位的值,{"token":"aiSf8jGqyPACcY3Myjxj"}。

 

不使用Devise的验证方法

阅读了Devise的文档,不知道是不是我会错意了,好似如果使用devise内置的auth_token方案,则web部分也会受到波及,需要使用authenticate_user!方法的地方都会额外验证auth_token,还需要修改devise.rb增加配置。

这里使用ruby-china一段很简单的验证方法,

 

  def current_user
    token = params[:auth_token] 
    @current_user ||= User.where(:authentication_token => token).first
  end

  def authenticate!
     render :status=>400,
            :json=>{:message=>"Need login."} unless current_user
  end

 这里相当于重新实现了一个API专用的current_user 和 authenticate_user! 方法。相应的只需要在将来需要进行登陆验证的API中都加入auth_token=xxx的参数即可。

 

 

这里额外写一段需要炎验证的Controller代码进行演示:

 

class Api::V1::ListController.rb < ApplicationController
  before_filter :authenticate!   #验证token
  
  respond_to :json 

  def index
    @lists=List.all.limit(10)
     render :status=>200, :json=> @lists
  end

end

 如果使用curl 进行测试,则额外的需要在get请求中写明auth_token的参数值,例如 

localhost:3000/api/v1/lists.json?auth_token=xxx

 

结束语

这段代码只是演示如果利用Rails与Devise快速的建立一套需要验证的API体系。