Closed redreeva closed 8 years ago
Yes, it's possible.
You're not sending what the captcha is creating though, so you should wrap the <div id="sample-captcha"></div>
in a <form>
which you can then serialize and send in the ajax request.
Let me know if you need any more details.
Bruno, thank you for response!
I do exactly what you mean, my captcha is in form and when I click "Send form" at first fires fields and captcha validation. Main question - what I do wrong? Why when form post and fires captcha validation this field
$frontendData = $captcha->getFrontendData();
is empty?
Bruno, I decided to look again this file visualCaptcha-PHP/app/app.php and I noticed this code at the top:
<?php
// Allow requests from all origins
$app->response[ 'Access-Control-Allow-Origin' ] = '*';
// Inject Session closure into app
$app->session = function() use( $app ) {
if ( $namespace = $app->request->params( 'namespace' ) ) {
$session = new \visualCaptcha\Session( 'visualcaptcha_' . $namespace );
} else {
$session = new \visualCaptcha\Session();
}
return $session;
};
I didn't do namespace check. Honestly i don't know how this check correctly implement in laravel. Is it important? I still in finding problem and understood why in captcha validation is nothing to check: we nothing sent, we just create a new object:
$session = new \visualCaptcha\Session();
$captcha = new \visualCaptcha\Captcha($session);
...
How can this work?
Hi, Eugeniya.
You don't need to worry about namespacing if you don't use more than one visualCaptcha instance per page.
I don't think you're sending the form data, but you say you are.
Can you add this before the $frontendData = $captcha->getFrontendData();
line:
echo '<pre>';
var_dump($_POST);
echo '</pre>';
And see what it shows in the ajax response?
If there's a public URL to see all this working together, it might be easier to spot the issue too.
Bruno, code you proposed displayed next:
<pre>
array(1) {
["code"]=>
string(1) "FasXX-12-GG"
}
</pre>
It's because I send in POST only text field value.
$.ajax({
url: '/game/checkCode' ,
type: 'POST',
headers: {
'X-CSRF-TOKEN': $('[name="_token"]').val()
},
data: { 'code': $('#start-form input[name=code]').val() },
success: function(data) {
...
}
});
I thought that I don't should send captcha value in post manually... Maybe my request is written incorrectly?
If you're not sending it, how will the app know about it? :)
You need to send it, that's why I said you should serialize the whole form. You can't reliably tell what the input name will be, or what the value is, that's handled by visualCaptcha itself.
Ok) In this case what value I have to send: selected image receives class 'visualCaptcha-selected', so I should to pass parameter of image data-index? And if it's true, so what I should compare with received value?
The comparison's done in the logic you see in the /try
route.
You don't need to pass any specific parameters. Like I said, it's best to send all inputs as they are, the idea is that you can't know for sure what will the input name be, or the value. It's all hashes, and the correct mapping is stored in the server session.
Bruno, you're right about serialize - now POST display captcha info:
data: "_token=WhH4gCMD7s6aBVJytPNp6ihU7vsdgv3eRysJIk0m&code=d&97e937faee4a4820a11f=ffe8dd4a3f1250dd445f"
But unfortunately result of this string:
$frontendData = $captcha->getFrontendData();
still is empty object.
That's what POST shows in the backend? How are you doing it in the $.ajax bit?
Yes.
$.ajax({
url: '/game/checkCode',
type: 'POST',
headers: {
'X-CSRF-TOKEN': $('[name="_token"]').val()
},
data: { data: $("form").serialize() },
success: function(data) {
...
}
});
Ok, change it to:
$.ajax({
url: '/game/checkCode',
type: 'POST',
headers: {
'X-CSRF-TOKEN': $('[name="_token"]').val()
},
data: $("form").serialize(),
success: function(data) {
...
}
});
So that the form data is sent as expected, instead of inside a data
property.
Now POST returns:
_token: "WhH4gCMD7s6aBVJytPNp6ihU7vsdgv3eRysJIk0m", code: "ddd", 12781b83c23b681fc7e1: "14b3d70b15cbe89a6838"
$frontendData is empty.
hmm. Can you see any session values?
visualCaptcha\Session
tries to use $_SESSION
, so if that doesn't work, you should either change it to some other Session class, like Laravel's, or try adding session_start();
in the beginning of the routes file, I guess.
Laravel Session class contains:
Object {_token: "WhH4gCMD7s6aBVJytPNp6ihU7vsdgv3eRysJIk0m", _previous: Object, flash: Object}
and $_SESSION shows:
Object {visualcaptcha: Array[0]}
Ok, turns out you need a couple of things for the XHR request:
Looking at http://stackoverflow.com/questions/2870371/why-is-jquerys-ajax-method-not-sending-my-session-cookie you should try changing your $.ajax
code to:
$.ajax({
url: '/game/checkCode',
type: 'POST',
xhrFields: {
withCredentials: true
}
headers: {
'X-CSRF-TOKEN': $('[name="_token"]').val()
},
data: $("form").serialize(),
success: function(data) {
...
}
});
If you get an error about CORS, try changing the first lines in app/app.php
from:
// Allow requests from all origins
$app->response[ 'Access-Control-Allow-Origin' ] = '*';
to:
// Allow requests from all origins
$app->response[ 'Access-Control-Allow-Origin' ] = 'http://YOURDOMAIN.com';
$app->response[ 'Access-Control-Allow-Credentials' ] = true;
And make sure to change YOURDOMAIN.com
to what you're using.
Let me know how that works out.
Maybe it's a little bit late for asking this question... :) Your captcha should to work on localhost?
Yes, but it won't work for Chrome: http://stackoverflow.com/questions/10883211/deadly-cors-when-http-localhost-is-the-origin you can easily do a workaround, like what's mentioned in that URL.
Bruno, thank you for yours fast replies, but nothing helps. I'll look for solutions for Laravel.
Ok. There are a couple of unofficial Laravel versions, see if any of those work for you: https://github.com/emotionLoop/visualCaptcha#unofficial-versions-created-by-community-members
Hello! Tell me please, can I use visualCaptcha without form submitted? Captcha displayed, refresh and audio buttons, "check is filled" are working but when I check captcha is nothing happens, here
is nothing contains. I hope you find problem :)
.routes.php
view:
captcha.js:
if clicked captcha checked button:
Thank you!