我有Devise的Rails 4应用程序。
最近,我发现对于某些操作,Humanizer功能无效。
问题:基本上它没有检查我关于安全问题的输入,并允许继续采取行动(但它不应该。)没有显示错误消息。
注意:Humanizer在用户注册过程中完美运行,但在编辑,密码恢复等操作中根本不起作用。
我的代码:
User.rb:
class User < ActiveRecord::Base
devise :database_authenticatable, :registerable,
:recoverable, :rememberable, :trackable, :validatable, :lockable, :confirmable
include Humanizer
attr_accessor :bypass_humanizer
require_human_on :create, :unless => :bypass_humanizer
...
end
的routes.rb
devise_for :users, :controllers => {:registrations=> "registrations", :confirmations=> "confirmations", :passwords => "passwords", :sessions => "sessions"}
Registrations_controller.rb
class RegistrationsController < Devise::RegistrationsController
clear_respond_to
respond_to :json
def sign_up_params
params.require(:user).permit( :email, :password, :country_id, :password_confirmation,:name, :not_a_robot,:current_password,:bypass_humanizer,:role, :humanizer_question_id, :humanizer_answer)
end
def account_update_params
params.require(:user).permit(:name, :email, :password, :country_id,:humanizer_answer, :password_confirmation, :current_password, :not_a_robot, :bypass_humanizer,:confirmation_token, :humanizer_question_id)
end
def destroy
#@p = current_user.id
@user = User.find(current_user.id)
@user.destroy
if @user.destroy
redirect_to root_path, notice: "User deleted."
end
end
private :sign_up_params
private :account_update_params
protected
def update_resource(resource, params)
resource.update_without_password(params)
end
end
Passwords_controller.rb
class PasswordsController < Devise::PasswordsController
respond_to :json, only: [:create]
skip_before_filter :age_check
def create
user = resource_class.send_reset_password_instructions(resource_params)
if successfully_sent?(user)
render json: { data: "something" }, status: 200
else
render json: { data: "something bad" }, status: 400
end
end
def update
self.resource = resource_class.reset_password_by_token(resource_params)
yield resource if block_given?
if resource.errors.empty?
resource.unlock_access! if unlockable?(resource)
if Devise.sign_in_after_reset_password
flash_message = resource.active_for_authentication? ? :updated : :updated_not_active
# set_flash_message!(:notice, flash_message)
sign_in(resource_name, resource)
else
# set_flash_message!(:notice, :updated_not_active)
end
# respond_with resource, location: after_resetting_password_path_for(resource)
redirect_to root_path
else
set_minimum_password_length
respond_with resource
end
end
end
密码恢复表单(Humanizer无法正常工作):
<%= form_for(@user,:html => {"data-parsley-validate" => true,:id=>"password-recover-modal",:class=>"password-recover-modal"},:remote=> true,format: :json,as: @user, url: password_path(@user)) do |f| %>
<div class="form-group">
<%= f.email_field :email, autofocus: true ,:class=> "user-input form-control", :id=>"email",:placeholder=>t('email'),required: true%>
</div>
<div class="question-content" style="position:relative;top:1px;">
<span class="question"><%= t('question') %>:</span>
<%= f.hidden_field :humanizer_question_id %>
<span class="answer">
<%= f.label :humanizer_answer, @user.humanizer_question %>
</span>
<div class="form-group" style="margin-bottom:21px;">
<span class="question" style="margin-top:8px;"><%= t('answer') %>: *</span>
<%= f.text_field :humanizer_answer ,:class=> "form-control",:required => true, :id=>"answer"%>
</div>
</div>
<%= f.submit t('recover_pass'),:class=> "blue-button btn btn-default"%>
<%end%>
用户注册表单(Humanizer完美运行):
<%= form_for(@user, :html => {:id=>"sign_up_user" ,:class=>"registration-form-modalc","data-parsley-validate" => true},remote: true, format: :json,as: @user, url: registration_path(@user)) do |f| %>
<div class="form-group">
<%= f.text_field :name,:class=> "user-input form-control", :id=>"user-name",autofocus: true ,:placeholder=> t('username_2'),:required => true,:'data-parsley-minlength'=>"3"%>
</div>
<div class="form-group">
<%= f.password_field :password,:id=>"passwordis",:class=> "user-input form-control", autocomplete: "off" ,:placeholder=> t('new_password'),:required => true,:'data-parsley-minlength'=>"8" %>
</div>
<div class="form-group">
<%= f.password_field :password_confirmation, :id=>"password-again",:class=> "user-input form-control", autocomplete: "off" ,:'data-parsley-equalto'=>"input#passwordis",:placeholder=> t('new_password_2'),:required => true,:'data-parsley-minlength'=>"8"%>
<%= f.hidden_field :role, :value => "user"%>
<%= f.hidden_field :country_id, :value => @location.id%>
</div>
<div class="form-group">
<%= f.email_field :email ,:class=>"user-input form-control" ,:'data-validatess' => '/blocked/checkemail',:id=>"emailito",:placeholder=> t('email'),:required => true%>
<h3 id="email-taken-message" style="display:none;margin-left:140px;color:red;padding-top:7px;"> <%= t('email_not_available') %> </h3>
</div>
<%= f.hidden_field :humanizer_question_id %>
<div class="question-content" style="position:relative;top:1px;">
<span class="question"><%= t('question') %>:</span>
<span class="answer">
<%= f.label :humanizer_answer, @user.humanizer_question %>
</span>
<div class="form-group" style="margin-bottom:21px;">
<span class="question" style="margin-top:8px;"><%= t('answer') %>: *</span>
<%= f.text_field :humanizer_answer ,:class=> "form-control",:required => true, :id=>"answer"%>
</div>
</div>
<%= f.submit t('confirm'),:class=> "blue-button btn btn-default"%>
<%end%>
我尝试使用密码恢复时从日志中提取
Started POST "/lv/users/password" for 85.254.76.76 at 2016-09-25 14:14:59 +0300
Processing by PasswordsController#create as JS
Parameters: {"utf8"=>"✓", "user"=>{"email"=>"myemail@gmail.com", "humanizer_question_id"=>"1", "humanizer_answer"=>"155"}, "commit"=>"ATGŪT PAROLI", "locale"=>"lv"}
[1m[36mCountry Load (0.4ms)[0m [1mSELECT `countries`.* FROM `countries` WHERE `countries`.`id` = 1 LIMIT 1[0m
[1m[35mRegion Load (0.5ms)[0m SELECT `regions`.* FROM `regions` WHERE `regions`.`country_id` = 1
[1m[36mPartner Load (0.4ms)[0m [1mSELECT `partners`.* FROM `partners` WHERE `partners`.`id` = 1 LIMIT 1[0m
[1m[35mUser Load (0.5ms)[0m SELECT `users`.* FROM `users` WHERE `users`.`email` = 'edgars.rworks@gmail.com' ORDER BY `users`.`id` ASC LIMIT 1
[1m[36mUser Load (247.6ms)[0m [1mSELECT `users`.* FROM `users` WHERE `users`.`reset_password_token` = '8ffe8d2b729cd77dd8f3b3df061e19076b87784edb5d4c10ee1466ee978257f7' ORDER BY `users`.`id` ASC LIMIT 1[0m
[1m[35m (0.3ms)[0m BEGIN
[1m[36mSQL (0.5ms)[0m [1mUPDATE `users` SET `reset_password_sent_at` = '2016-09-25 14:15:00', `reset_password_token` = '8ffe8d2b729cd77dd8f3b3df061e19076b87784edb5d4c10ee1466ee978257f7', `updated_at` = '2016-09-25 14:15:00' WHERE `users`.`id` = 169[0m
[1m[35m (0.3ms)[0m COMMIT
Rendered devise/mailer/reset_password_instructions.html.erb (4.5ms)
Devise::Mailer#reset_password_instructions: processed outbound mail in 268.7ms
Sent mail to myemail@gmail.com (129.2ms)
Date: Sun, 25 Sep 2016 14:15:00 +0300
From: support@.eu
Reply-To: support@.eu
To: @gmail.com
Message-ID: <57e7b1b4edb10_c48e740a6dc92516@if36.nano.lv.mail>
Subject: Reset password instructions
Mime-Version: 1.0
Content-Type: text/html;
charset=UTF-8
Content-Transfer-Encoding: quoted-printable
<html>
<head>
<meta content=3D'text/html; charset=3DUTF-8' http-equiv=3D'Content-Ty=
pe' />
</head>
<body>
<h3> Sveicin=C4=81ti, admins !</h3>
=
<p> K=C4=81ds ir piepras=C4=ABjis saiti, lai main=C4=ABtu paroli. To=
var izdar=C4=ABt, izmantojot zem=C4=81k nor=C4=81d=C4=ABto saiti.</p>
=
<p><a href=3D"http://www.individualki.eu/users/password/edit?reset_p=
assword_token=3Dpq9s-yq74P1mwRFui13L">Main=C4=ABt savu paroli</a></p>
<p></p>
<p>Ja J=C5=ABs neesat piepras=C4=ABjis =C5=A1o, l=C5=ABdzu, ne=C5=86=
emiet v=C4=93r=C4=81 =C5=A1o e-pasta zi=C5=86ojumu.</p>
=
<p></p>
<p>Parole nemain=C4=ABsies, ja J=C5=ABs nespied=C4=ABsiet uz saites a=
ug=C5=A1=C4=81 un nemain=C4=ABsiet to.</p>
</body>
</html>
Completed 200 OK in 1616ms (Views: 0.7ms | ActiveRecord: 260.9ms)
答案 0 :(得分:0)
由于我无法找到人工化器默认行为无效的原因所以我强制使用Humanizer验证,如example
def create
ad = User.new
ad.humanizer_question_id = params[:user][:humanizer_question_id]
ad.humanizer_answer = params[:user][:humanizer_answer]
if ad.humanizer_answer.present? && ad.humanizer_question_id.present?
if ad.humanizer_correct_answer?
usero = resource_class.send_reset_password_instructions(resource_params)
if successfully_sent?(usero)
render json: { data: "something good" }, status: 200
else
render json: { data: "something bad successfully_sent?(usero)" }, status: 400
end
else
render json: { data: "Humanizer wrong ad.humanizer_correct_answer?" }, status: 400
end
else
render json: { data: "ad.humanizer_answer.present? || ad.humanizer_question_id.present?" }, status: 400
end
end