token in rails

构建背景: rails + device

1. 在user中增加authentication_token字段后

#models/user.rb
class User < ActiveRecord::Base
  before_save :ensure_authentication_token
  .......

  # token为空时自动生成新的token
  def ensure_authentication_token
    if authentication_token.blank?
      self.authentication_token = generate_authentication_token
    end
  end

  private
# 保证tokend的唯一 def generate_authentication_token loop do token = Devise.friendly_token break token unless User.where(authentication_token: token).first end end end

2. 为程序全局添加一个token认证方法

 

#controllers/application_controller.rb

class ApplicationController < ActionController::Base
  # 因为用作API,所以关闭防CSRF不然会出问题
  protect_from_forgery with: :null_session

  private

  # 获取http:/xxx.com/books.json?token=aMUj5kiyLbmZdjpr_iAu
  # 判断token的值是否存在,若存在且能在User表中找到相应的,就登录此用户
  def authenticate_user_from_token!
    token = params[:token].presence
    user = token && User.find_by_authentication_token(token.to_s)
    if user
      sign_in user, store: false
    end
  end

end


3. 让登录、注册返回token

##app/controllers/users/registrations_controller.rb
  def create
    @user = User.new(user_params)
    respond_to do |format|
      if @user.save
        format.json { render json: { success: true, token:@user.authentication_token, user_id:@user.id }}
      end
    end
  end
  
  private
  def user_params
    params.require(:user).permit(:email, :password, :password_confirmation)
  end

#app/controllers/users/sessions_controller.rb
  def create
    ##验证邮箱是否存在
    user = User.find_for_database_authentication(:email => params[:user][:email])
    return render json: {error: {status:-1}} unless user

    respond_to do |format|
      #验证密码是否正确
      if resource.valid_password?(params[:user][:password])
        sign_in("user", user)
        user.ensure_authentication_token
        format.json { 
          render json: {token:user.authentication_token, user_id: user.id}
        }
      else
        format.json {
          render json: {error: {status:-1}}
        }
      end
    end
  end
  
  #注销就是更换用户token
  def destroy
    current_user.authentication_token = Devise.friendly_token
    sign_out(current_user)
    render json: {success: true}
  end

使用

1.客户端发送帐号密码到服务端,服务器验证成功后返回token,客户端将token保存在本地

2.在需要认证身份的请求(GET、POST、DELETE)的url后加上?user=xxxxxxxxxx这样的字串,比如:

http:/xxx.com/books.json?token=aMUj5kiyLbmZdjpr_iAu

用curl发送请求举例:

 

 

#注册
curl -X POST -H 'Content-Type: application/json' -d '{"user":{"password":"12345678","password_confirmation":"12345678","email": "12345678@x.com"}}' http://localhost:3000/users.json

#登录
curl -X POST -H 'Content-Type: application/json' -d '{"user":{"email": "12345678@x.com","password": "12345678"}}' http://localhost:3000/users/sign_in

#得到返回json:
{"user_token":"aMUj5kiyLbmZdjpr_iAu","user_id":1}

#新建comment
curl -X POST -H "Content-Type: application/json" -d '{"comment":{"comment_content":"test"}}' localhost:3000/comments.json?user_token=aMUj5kiyLbmZdjpr_iAu

 

 

 

 

 

 

 

 

 

 

 

 

 

 


posted @ 2015-06-25 16:26  耿小曾  阅读(453)  评论(0编辑  收藏  举报