recaptcha icon indicating copy to clipboard operation
recaptcha copied to clipboard

Verify captcha Message in Production

Open interpegasus opened this issue 6 years ago • 3 comments

Issue

The capthca works locally in both development and production modes. But it does not work when it is deployed. It returns a message: "Verify captcha"

I would like to know how to fix the issue? Or if this is a bug. Thanks.

Steps to reproduce

Ruby Info

  ruby:
    interpreter:  "ruby"
    version:      "2.3.1p112"
  rails: 5.1

Model

def signup
    @user = User.new(user_params)    

    # Referral Code
    referral_code = params[:user][:referral_code].to_s
    referral_code = cookies[:h_ref].to_s if referral_code.blank?

    unless referral_code.blank?
      referee = User.find_by(referral_code: referral_code)
      unless referee.nil?
        @user.referrer = referee
        referee.referrals << @user
      end
    end

    respond_to do |format|
      if verify_recaptcha(secret_key:'GOOGLE_CAPTCHA_SECRET_KEY_IS_REPLACED_HERE', model: @user, message: 'Error in passing CAPTCHA.') && @user.save        
        @notice = 'Registration was successful.'
        send_email
        format.html { render :login }
        format.json { render :show, status: :created, location: @user }
      else
        format.html { render :signup }
        format.json { render json: @user.errors, status: :unprocessable_entity }
      end
    end
  end

View

<%= form_for(@user, url: 'signup', html: {class: 'ui large error form'}) do |form| %>
		<div class="ui segment">
			<% if @user.errors[:username].any? %>
			<div class="field error">
				<% else %>
				<div class="field">
					<% end %>
					<div class="ui input">
						<%= form.text_field :username, id: :user_username, placeholder: 'Username' %>
					</div>
				</div>
				<% if @user.errors[:email].any? %>
				<div class="field error">
					<% else %>
					<div class="field">
						<% end %>
						<div class="ui input">
							<%= form.text_field :email, id: :user_email, placeholder: 'Email' %>
						</div>
					</div>
					<% if @user.errors[:password_hash].any? %>
					<div class="field error">
						<% else %>
						<div class="field">
							<% end %>
							<div class="ui input">
								<%= form.text_field :password, id: :user_password, type: 'password', placeholder: 'Password' %>
							</div>
						</div>
						<div class="field">
							<div class="ui input">
								<%= form.text_field :referral_code, id: :referral_code, placeholder: 'Referral Code' %>
							</div>
						</div>
						<div class="field">
							<%= recaptcha_tags site_key: 'GOOGLE_CAPTCHA_SITE_KEY_IS_REPLACED_HERE' %>
						</div>
						<div class="actions">
							<%= form.submit value:'Create', class: 'ui fluid large blue submit button' %>
						</div>
					</div>
					<% if @user.errors.any? %>
					<div class="ui error message">
						<ul class="list">
							<% @user.errors.full_messages.each do |message| %>
							<li><%= message %></li>
							<% end %>
						</ul>
					</div>
					<% end %>
					<% end %>

interpegasus avatar May 17 '18 00:05 interpegasus

Response error in passing captcha

interpegasus avatar May 17 '18 00:05 interpegasus

Implementation Solution Without the Gem

During the meanwhile the following works. It adds a captcha client side, and validates the response server side.

View

<script type="text/javascript">
  var widgetId1;
  var onloadCallback = function() {
    widgetId1 = grecaptcha.render('html_element', {
      'sitekey' : 'YOUR KEY,
      'callback' : verifyCallback,
      'theme' : 'dark'
    });
  };
  var verifyCallback = function(response) {        
    $.post('/verify_captcha',{response:response})
    .done(function( data ) {      
      if( data.success ){
        $("#submitButton").prop('disabled', false);
      } else {
        $("#submitButton").prop('disabled', true);
      }
    });
  };
</script>

// INSIDE THE FORM
      <div class="field">
        <div id="html_element"></div>
        <script src="https://www.google.com/recaptcha/api.js?onload=onloadCallback&render=explicit"
        async defer>
      </script>
      </div>

<input disabled="disabled" id="submitButton" value="Button Name" type="submit" class="ui fluid large blue submit button" />          

routes post 'verify_captcha', to: 'auth#verify_captcha'

model

def verify_captcha
   require 'uri'
   require 'net/http'
   uri = URI("https://www.google.com/recaptcha/api/siteverify")
   https = Net::HTTP.new(uri.host, uri.port)
   https.use_ssl = true
   verify_request = Net::HTTP::Post.new(uri.path)
   verify_request["secret"]    = 'YOU SITE SECRET'
   verify_request["remoteip"]  = request.remote_ip 
   verify_request["response"]  = params[:response] 
   response = https.request(verify_request)    
   render json: {success: true, response: response.body}, status: 200
   return 
 end

interpegasus avatar May 17 '18 18:05 interpegasus

no idea what this issue is ... debugging "works locally but not on my server" is also not really possible try checking the logs if the param gets send in, maybe add more logging seems really fishy

grosser avatar May 18 '18 04:05 grosser