Devise Rails 3.2.22 remember_user_token未设置

时间:2016-03-03 10:16:26

标签: ruby-on-rails ruby ruby-on-rails-3 cookies devise

我试图通过设计3.5.2和rails 3.2.22来管理一些奇怪的问题。

问题是设计没有设置remember_user_token cookie。 我的应用程序是一个API,所以我有sessions_controller覆盖。

def create
  # build_resource
  resource = User.find_for_database_authentication(email: params[:email])
  return invalid_login_attempt(email: t('api.errors.email.user_not_exists', email: params[:email])) unless resource

  unless resource.active_for_authentication?
    render json: { success: false }.merge(errors: t('api.errors.email.inactive')), status: :ok
    return
  end

  if resource.is_deleted
    render json: { success: false }.merge(errors: t('api.errors.email.deleted')), status: :ok
    return
  end

  if resource.valid_password?(params[:password])
    sign_in("user", resource)
    resource.enable_beta unless resource.beta_enabled?
    render json: { success: true }.merge(user: resource.as_json(user: resource)), status: :ok
    return
  end
  invalid_login_attempt(password: t('api.errors.email.wrong_password'))
end

这是我的用户模型(设计部分)

# Extensions
devise :database_authenticatable, :registerable, :confirmable,
     :recoverable, :rememberable, :trackable, :validatable,  :lastseenable

登录就像一个魅力,但没有设置remember_user_token cookie。

Started POST "/api/v1/users/sign_in" for 127.0.0.1 at 2016-03-03 16:09:23 +0600
Processing by API::V1::SessionsController#create as JSON
Parameters: {"email"=>"email@gmail.com", "password"=>"[FILTERED]",  "remember_me"=>true, "session"=>{"email"=>"email@gmail.com", "password"=>" [FILTERED]", "remember_me"=>true}}
User Load (0.7ms)  SELECT "users".* FROM "users" WHERE "users"."is_deleted" = 'f' AND "users"."email" = 'email@gmail.com' LIMIT 1
(0.2ms)  BEGIN
(0.5ms)  UPDATE "users" SET "last_sign_in_at" = '2016-03-03  10:06:43.642950', "current_sign_in_at" = '2016-03-03 10:09:23.152373',  "sign_in_count" = 179, "updated_at" = '2016-03-03 10:09:23.154418',  "users_for_mentions" = '---
- ''no''
' WHERE "users"."id" = 300
Tag Load (0.4ms)  SELECT "tags".* FROM "tags" WHERE "tags"."host_id" =  300 AND "tags"."host_type" = 'User' LIMIT 1
(0.5ms)  COMMIT
User Load (0.5ms)  SELECT "users".* FROM "users" WHERE "users"."id" = $1 LIMIT 1  [["id", 300]]
City Load (0.3ms)  SELECT "cities".* FROM "cities" WHERE "cities"."id" =  3 LIMIT 1
Completed 200 OK in 2515.4ms (Views: 8.7ms | ActiveRecord: 4.4ms |  Sphinx: 0.0ms)

cookie browser 我也尝试用手设置cookie:

  cookies["remember_user_token"] = {
    value: user.class.serialize_into_cookie(user.reload),
    expires: 3.year.from_now,
    domain: RAILS_DOMAIN
  }

但也没有运气。似乎某些东西阻止了cookie的设置。你能分享一下你的想法吗?

提前致谢。

1 个答案:

答案 0 :(得分:0)

答案非常简单,并在GitHub上的Devise源代码中进行了解释

module Devise
  module Controllers
  # A module that may be optionally included in a controller in order
  # to provide remember me behavior. Useful when signing in is done
  # through a callback, like in OmniAuth.

所以,我需要做的就是在我的控制器中包含适当的模块,并在方法中添加两行

module API::V1
  class SessionsController < Devise::SessionsController
  include Devise::Controllers::Rememberable
  prepend_before_filter :require_no_authentication, only: [:create]

  include Corsable

  ...

  def create
  # build_resource
    resource = User.find_for_database_authentication(email:   params[:email])
    return invalid_login_attempt(email:   t('api.errors.email.user_not_exists', email: params[:email])) unless   resource

    unless resource.active_for_authentication?
      render json: { success: false }.merge(errors: t('api.errors.email.inactive')), status: :ok
      return
    end

    if resource.is_deleted
      render json: { success: false }.merge(errors: t('api.errors.email.deleted')), status: :ok
      return
    end

    if resource.valid_password?(params[:password])
      sign_in(resource)
      remember_me(resource) if params["remember_me"].present?
      resource.enable_beta unless resource.beta_enabled?
      render json: { success: true }.merge(user: resource.as_json(user: resource)), status: :ok
      return
    end
    invalid_login_attempt(password: t('api.errors.email.wrong_password'))
  end

  def destroy
    forget_me(current_user)
    sign_out(resource_name)
    respond_to do |format|
      format.json { render json: '', status: :no_content }
    end
  end
end