I want add a captcha feature on my login page. So I follow this page to do.
# coding: utf-8
class SessionsController < Devise::SessionsController
def new
session[:return_url] = params[:return] if !params[:return].blank?
super
end
def create
if verify_recaptcha
super
else
build_resource
# clean_up_passwords(resource)
flash[:error] = "Captcha has wrong, try a again."
respond_with_navigational(resource) { render :new }
end
end
end
When I first submit with a bad captcha code, will got Captcha has wrong, try a again. message, but when I refresh that page again, the devise will auto login.
Started POST "/account/sign_in" for 127.0.0.1 at 2012-10-17 22:33:09 +0800
Creating scope :recent. Overwriting existing method User.recent.
Creating scope :exclude_ids. Overwriting existing method User.exclude_ids.
Processing by SessionsController#create as HTML
Parameters: {"utf8"=>"✓", "authenticity_token"=>"zqnzxilphdasnIGkHqRH1saD4a4w/Eee/ef3OaWRyT8=", "user"=>{"email"=>"[email protected]", "password"=>"[FILTERED]", "captcha"=>"WWW", "remember_me"=>"0"}, "commit"=>"登录"}
MONGODB (2ms) movieso_dev['system.namespaces'].find({})
MONGODB (0ms) movieso_dev['users'].find({:_id=>2923}).limit(-1).sort([[:_id, :asc]])
Redirected to http://127.0.0.1:3000/
Filter chain halted as :require_no_authentication rendered or redirected
Completed 302 Found in 5ms (Search: 0.0ms)
Looks like require_no_authentication has did login and redirect the page.
https://github.com/plataformatec/devise/blob/master/app/controllers/devise_controller.rb#L122
So, I add a skip_before_filter to disable that feature, and verify logic will be work fine!
class SessionsController < Devise::SessionsController
skip_before_filter :require_no_authentication, :only => [ :new, :create]
.....
end
Sounds good. Could you please update the wiki page? They are maintained by the community, so feel free to change it.
This change doesn't seem to work anymore.
Using omniauth (1.1.4)
Using omniauth-oauth2 (1.1.1)
Using omniauth-facebook (1.4.1)
Using recaptcha (0.3.5)
Using devise (2.2.3)
class SessionsController < Devise::SessionsController
skip_before_filter :require_no_authentication, :only => [:new, :create]
def create
if verify_recaptcha
super
else
build_resource
flash[:notice] = "Incorrect Captcha entry, try again."
respond_with_navigational(resource) { render :new }
end
end
end
And logins are getting authorized even though the captcha is failing.
Any ideas? Trying to find out if devise 2.2.3 changed the before filter...
EDIT: I just realized this is probably because I'm using Omniauth and there must be an additional helper that needs to be run in order to verify the captcha before the omniauth login.
We meet this problem too. and just did that like huacnlee, but the skip_before_filter :require_no_authentication, :only => [ :new, :create] is no use for us.
we wrap the captcha valid in prepend_before_filter :captcha_valid, :only => [ :create] that will be ok.
It's been changed, any ideas?
@chinacheng Great! Your solution fits my issue!
I've encountered the exact same issue, and I can't seem to solve it. This is my implementation
using ruby 1.9.3p547 and rails 3.2.21:
class SessionsController < Devise::SessionsController
skip_before_filter :require_no_authentication, :only => [:new, :create]
# POST /resource/sign_in
def create
if verify_recaptcha
super
else
render :new
end
end
end
I'm not quite understanding what is happening here. Devise's implementation of SessionsController has this on top of the file:
prepend_before_filter :require_no_authentication, :only => [ :new, :create ]
Which in plain English means: I don't have to be authenticated to view the sign-in form or to post a sign-in request. However, the behavior I see is the following:
signed_in? is instantly true at the beginning of the create action, even before it calls super.So to counteract this _before_ filter, I have to write
skip_before_filter :require_no_authentication, :only => [ :new, :create ]
Why should in add only => [ :new, :create ], and not just only => [ :create ]?
Can anyone help me?
Using @chinacheng's idea and this post on RoR 4 with Recaptcha gem, is as simple as:
class Users::SessionsController < Devise::SessionsController
prepend_before_action :captcha_valid, only: [:create]
layout "login"
private
def captcha_valid
if verify_recaptcha
true
else
self.resource = resource_class.new(sign_in_params)
respond_with_navigational(resource) { render :new }
end
end
end
@guapolo Added that to the wiki
Most helpful comment
Using @chinacheng's idea and this post on RoR 4 with Recaptcha gem, is as simple as: