Nová reCAPTCHA pro formuláře
- uestla
- Backer | 799
[Staré vlákno již zemřelo, založil jsem proto nové]
ReCaptchaControl 2
Aktualizoval jsem doplněk přidávající reCAPTCHu do formulářů, protože se na scéně objevila její nová (a příjemnější) verze.
Budu rád za jakékoli připomínky.
Ať slouží.
Editoval uestla (25. 6. 2017 2:13)
- Oli
- Člen | 1215
Ahoj, díky za doplněk. Měl jsem problém od verze 2.0.1. ReCaptcha se mi
nechtěla zobrazit. Vyřešil jsem to až podle dokumentace google. Dokud jsem
tam nedal ten onload=onloadCallback
, tak mi to psalo, že
grecaptcha
je neznámu funkce. Možná jsem ale něco dělal
blbě já.
<script src="https://www.google.com/recaptcha/api.js?onload=onloadCallback&render=explicit"></script>
var onloadCallback = function() {
$('.g-recaptcha').each(function () {
var el = $(this);
grecaptcha.render(el[0], {
sitekey: el.attr('data-sitekey')
});
});
};
- uestla
- Backer | 799
Také jsem to řešil. Problém byl, že oni radí načítat jejich script v hlavičce. Ale když chci vykreslovat explicitně, musí v momentě ten předávaný callback už existovat, tj. i jQuery by myslím mělo být načtené (i když je-li to callback, teoreticky by nemuselo – vyzkouším to), a jQuery načítám až vespod stránky.
Dám vědět a kdyžtak updatuju README. Díky.
- uestla
- Backer | 799
Tak nakonec byl problém v tom, že jsem zvyklý javascripty psát stylem
;(function (window, $) {
function onReCaptchaLoad() {
// ...
}
})(window, window.jQuery);
tam, kde používám jQuery. To by ale vyžadovalo načtenost jQuery ještě před načtením reCAPTCHA api. To by ostatně nevadilo, proto jsem updatoval přiložený script, aby byl pokud možno co nejrobustnější.
- Felix
- Nette Core | 1196
Vim, ze je to dost podobne. Nicmene jsem to mel v kompu jiz delsi dobu, akorat jsem to nehodil na github.
- webdata
- Člen | 153
uestla napsal(a):
Formulář se odešle a výsledek je jaký? Nezapomínáš navěšovat validační pravidlo? Nebo máš na mysli nevalidování se na straně javascriptu? To totiž není implementované.
Vše mám dle readme na gitu. Formulář vykresluji ručně a vše funguje tak jak má. Ale captch je tam prostě na ozdobu, je jedno zda se uživatel ověří nebo ne. Protože žádná hláška typu ‚dokaž že jsi člověk‘ nikde nevyskočí i přesto, že mám ošetřený výpis chyb formuláře.
- Pavel Kravčík
- Člen | 1194
@duff123: Je to rozbitý a nefunguje to.
- Kontrola composer.json (je to tam správě napsané?)
- Composer update (proběhne bez chyb?)
- Kontrola vendor složky (je fyzicky složka uestla\Catchpa?)
- Volání se správným namespace (\ReCaptcha, nebo use)
- H0w4rd
- Člen | 96
Prosím jak to mám udělat, když mám projekt, který běží pod několika doménama a potřebuju mít více site key a secret key?
Ideálně bych potřeboval, aby ve třídě ReCaptcha byl setter pro $siteKey a $secretKey.
Potom bych totiž mohl při vytváření formuláře udělat:
$form["captcha"]->getReCaptcha()->setSiteKey("bbbb")->setSecretKey("aaaaaa");
Bylo by možné udělat takovou úpravu?
Nebo je jiná možnost, jak měnit site key a secret key podle situace?
Editoval H0w4rd (3. 2. 2016 16:45)
- uestla
- Backer | 799
To je zajímavá situace, nenapadlo mě, že takový scénář může nastat. V tuhle chvíli je bohužel celá extension napevno svázaná s jedním siteKey a secretKey, aniž by se dala měnit (implementaci setterů považuji za trochu nešťastnou, protože by se přepsala pro celý zbytek aplikace v rámci daného requestu).
Jako možné rozšíření mě napadlo přidat možnost nastavit několik „namespace“, kdy by každý měl svůj siteKey a secretKey a při vkládání prvku do formuláře by měl uživatel možnost zvolit, který z namespaců chce použít (s tím, že defaultně by se vybíral ten první).
Bohužel teď neoplývám dostatkem volného času, abych něco takového napsal, čili jestli má někdo chuť a pochopil mnou nastíněné řešení, nebo někoho napadlo nějaké lepší, jsem pullům otevřen :-)
- H0w4rd
- Člen | 96
Problém je v tom, že sami uživatelé si budou moct ty domény založit, když se zaregistrují do aplikace a zadají si tam tu svou doménu (potom už si sami nasměrují DNS záznam A nebo CNAME), nastaví si nějaké parametry a webová aplikace jim pojede na jejich doméně s jejich nastavením. No a potřebuju, aby si sami mohli zadat i ty klíče pro recaptchu. Není možné, abych ty klíče povoloval třeba já, že by mi třeba chodily mailem po registraci, to bych se z toho zbláznil. A všem uživatelům přístup do té správy také dát nemohu.
S těmi namespace jsem to příliš nepochopil. Hlavně ale potřebuju, aby se ty klíče mohly brát z databáze.
Škoda, ten setter by mi problém vyřešil. Bylo by mi jedno, že by se to změnilo pro celý zbytek aplikace v rámci daného requestu, ta recaptcha je na stránce jen jedna, čemu by to vadilo?
Nebylo by třeba možné, abych klíče zadával už tady?
$form->addReCaptcha('captcha', "sdfasdfdasfdasfasd", "fdasfasdfsdafsa");
Editoval H0w4rd (3. 2. 2016 21:55)
- H0w4rd
- Člen | 96
Diky, udelal jsem to tak a funguje to.
Mam s tim jenom jeden mensi problem:
Metody getSiteKey a getSecretKey z te tridy Config se volaji pri kazdem
requestu, i kdyz na strance recaptcha neni. Jak tomu zabranit? Zbytecne se
posila dotaz do databaze.
Editoval H0w4rd (4. 2. 2016 11:46)
- randallll
- Člen | 22
webdata napsal(a):
Takže jsem zkoušel nasadit captchu, vše OK ale až na jedno. Captcha se sice zobrazí ale je úplně jedno zda se ověřím nebo ne – formulář se stejně odešle. Jinak to zkouším na nette 2.3.1 a formulář renderuji ručně (možná to bude ten problém).
tohle jeste nikdo neopravil ??? dik
- Václav Kraus
- Člen | 77
@randallll Já to používám na několika projektech a tento problém jsem ještě neměl. Takže nejspíš ano :)
- randallll
- Člen | 22
extensions:
translation: Kdyby\Translation\DI\TranslationExtension
reCaptcha: ReCaptchaControl\ReCaptchaExtension
translation:
debugger: on
default: en
fallback: [en_En, en]
whitelist: ['cs', 'en', 'pl', 'es', 'fr', 'ge', 'it', 'ru', 'sk', 'se']
reCaptcha:
siteKey: ***
secretKey: ***
methodName: 'addReCaptcha'
<?php
public function createComponentContactForm() {
$form = new Form();
//$form->getElementPrototype()->class('ajax');
$form->addHidden('to_email')
->setAttribute('id', 'to_email');
$form->addText('name', $this->translator->translate('default.contact.form_name'))
->setAttribute('placeholder', $this->translator->translate('default.contact.form_name'))
->setRequired($this->translator->translate('default.contact.form_message_required', NULL, array('label' => '%label')))
->addRule(Form::MAX_LENGTH, $this->translator->translate("default.contact.form_message_max_length", NULL, array('label' => '%label', 'value' => '%value')), 50);
$form->addText('company', $this->translator->translate('default.contact.form_company'))
->setAttribute('placeholder', $this->translator->translate('default.contact.form_company'))
->addCondition(Form::FILLED)
->addRule(Form::MAX_LENGTH, $this->translator->translate("default.contact.form_message_max_length", NULL, array('label' => '%label', 'value' => '%value')), 50);
$form->addText('email', $this->translator->translate('default.contact.form_your_email'))
->setAttribute('placeholder', $this->translator->translate('default.contact.form_your_email'))
->setRequired($this->translator->translate('default.contact.form_message_required', NULL, array('label' => '%label')))
->addRule(Form::EMAIL, $this->translator->translate("default.contact.form_message_email", NULL, array('label' => '%label')))
->addRule(Form::MAX_LENGTH, $this->translator->translate("default.contact.form_message_max_length", NULL, array('label' => '%label', 'value' => '%value')), 50);
$form->addText('subject', $this->translator->translate('default.contact.form_subject'))
->setAttribute('placeholder', $this->translator->translate('default.contact.form_subject'))
->setRequired($this->translator->translate('default.contact.form_message_required', NULL, array('label' => '%label')))
->addRule(Form::MAX_LENGTH, $this->translator->translate("default.contact.form_message_max_length", NULL, array('label' => '%label', 'value' => '%value')), 50);
$form->addTextArea('message', $this->translator->translate('default.contact.form_message'))
->setAttribute('cols', 5)
->setAttribute('rows', 6)
->setAttribute('placeholder', $this->translator->translate('default.contact.form_message'))
->setRequired($this->translator->translate('default.contact.form_message_required', NULL, array('label' => '%label')))
->addRule(Form::MAX_LENGTH, $this->translator->translate("default.contact.form_message_max_length", NULL, array('label' => '%label', 'value' => '%value')), 50);
$form->addReCaptcha('captcha', $this->translator->translate('default.contact.form_verification'))
->addRule(\ReCaptchaControl\ReCaptchaControl::VALID, $this->translator->translate('default.contact.form_message_verification'));
$form->addButton('cancel', $this->translator->translate('default.contact.form_cancel'))
->setAttribute('data-dismiss', 'modal')
->setAttribute('aria-label', 'Close')
->setAttribute('class', "btn btn-default");
$form->addSubmit('send', $this->translator->translate('default.contact.form_submit'))
->setAttribute('class', "btn btn-primary");
return $form;
}
?>
<div class="modal fade" id="modalSendEmail" tabindex="-1" role="dialog" aria-labelledby="contactLabel">
<div class="modal-dialog" role="document">
<div class="modal-content">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal" aria-label="Close"><span aria-hidden="true">×</span></button>
<h4 class="modal-title" id="myModalLabel">{_default.contact.modal_title}</h4>
</div>
<div class="modal-body">
{snippet contactForm}
{control contactForm}
{/snippet}
</div>
</div>
</div>
</div>
Editoval randallll (23. 2. 2016 19:46)
- uestla
- Backer | 799
Ve verzi 3 došlo k hlavní úpravě, a sice, že validační pravidlo se navěšuje rovnou, tedy ne ručně – upravil jsem podle toho instrukce a ukázku v úvodním příspěvku.
- GEpic
- Člen | 566
EDIT:
Stejně jako se psalo víše, mám v tuto chvíli reCaptchu pouze pro ozdobu.
Neudělal jsem nic víc, než je implementace dle tvého githubu. Vykresluji
formulář ručně, každopádně zkoušel jsem i {control contactForm} a
taktéž bez úspěchu.
{form contactForm}
<div class="form-group icon">
<div class="control input">
{input name}
<i class="fa fa-user"></i>
</div>
</div>
<div class="form-group icon">
<div class="control input last">
{input email}
<i class="fa fa-envelope"></i>
</div>
</div>
<div class="form-group icon">
<div class="control input textarea">
{input message}
<i class="fa fa-comment"></i>
</div>
</div>
<div class="form-group">
{input captcha}
</div>
<div class="form-group">
{input submit class => 'btn btn-xlg btn-primary'}
</div>
{/form}
PS: Formulář zpracovávám kompletně v onSubmit
, je to takto
správně?
Editoval GEpic (3. 7. 2016 3:26)
- GEpic
- Člen | 566
Pořád stejné. Navíc nyní
$f->addReCaptcha('captcha', NULL, "Please prove you're not a robot.");
nelze samostatně využít kvůli
Missing setRequired(TRUE | FALSE)
.
Přikládám i svůj formulář, na kterém to testuji:
protected function createComponentContactForm()
{
$f = new Form;
$f->addText("name", "Jméno:")
->setRequired("Musíte vyplnit jméno!")
->setAttribute("placeholder", "Jméno")
->setAttribute("class", "form-control");
$f->addText("email", "Email:")
->setRequired("Musíte vyplnit email!")
->addRule(Form::EMAIL, "Email není ve správném tvaru")
->setAttribute("placeholder", "Váš email")
->setAttribute("class", "form-control");
$f->addTextArea("message", "Zpráva")
->setAttribute("placeholder", "Zpráva")
->setRequired("Musíte vyplnit zprávu")
->setAttribute("class", "form-control")
->setAttribute("rows", 7);
$f->addReCaptcha('captcha', NULL, "Please prove you're not a robot.");
#->setRequired(true / false - nic se nezmění)
$f->addSubmit("submit", "Odeslat");
$f->onSuccess[] = function (Form $f) {
$v = $f->getValues(true);
$this->email->sendMessageEmail($v['name'], $v['email'], $v['message']);
$this->redirect("this#contactFormAnchor", ["sent" => true]);
};
return $f;
}
Editoval GEpic (3. 7. 2016 11:24)
- GEpic
- Člen | 566
uestla napsal(a):
@GEpic Nejspíš nemáš verzi 4 – v ní už se
setRequired()
volá. Zkus si spustittests/basic.php
v prohlížeči, jestli ti bude fungovat…
Sem kre*én :) … Samozřejmě že s tímto v composeru –
"uestla/recaptcha-control": "3.*"
to fungovat nebude.
Díky, funguje skvěle!
Editoval GEpic (3. 7. 2016 14:52)
- dubblen
- Člen | 9
Dobrý den,
pokouším se již nějaký pátek rozchodit recaptchu, ale bohužel bez úspěchu. ReCaptcha se mi vykresluje, ale bohužel nelze formulář odeslat. Do JS console se vypisuje: „Error: ReCAPTCHA placeholder element must be empty“. API key mám zaregistrované u Google. Domény také přidané.
Neone config:
extensions:
reCaptcha: ReCaptchaControl\ReCaptchaExtension
reCaptcha:
siteKey: '*můjKey*'
secretKey: '*můjKey*'
methodName: 'addReCaptcha' # optional
Továrničku mám takto:
public function create()
{
$form = new Form;
$form->addText('nickname', 'Jméno:')
->setRequired('Prosím, zadejte vaše jméno.');
$form->addText('headline', 'Nadpis::')
->setRequired('Prosím, zadejte nadpis.');
$form->addText('email', 'E-mail:')
->setRequired('Prosím zadejte váš email.');
$form->addTextArea('text')
->setRequired('Napoložili jste žádný dotaz.');
$form->addReCaptcha('recaptcha', NULL, "Please prove you're not a robot.")
->setRequired('Napoložili jste žádný dotaz.');
$form->addSubmit('send', 'Odeslat');
$form->onSuccess[] = array($this, 'formSucceeded');
return $form;
}
public function formSucceeded($form)
{
...
}
Poté v šabloně takto:
{form commentForm}
...
<div n:name="recaptcha"></div>
...
{/form}
Zkoušel jsem i takto:
{form commentForm}
...
{input recaptcha}
...
{/form}
prosím o pomoc, už si nevím rady. Děkuju…
Editoval dubblen (19. 8. 2016 6:58)
- dubblen
- Člen | 9
GEpic napsal(a):
Zkus změnit toto:
$form->addReCaptcha('recaptcha', NULL, "Please prove you're not a robot.") ->setRequired('Napoložili jste žádný dotaz.');
Na:
$form->addReCaptcha('recaptcha', NULL, "Please prove you're not a robot.");
Děkuju za radu, bohužel ale nepomohlo.
Jediné co to udělá je to, že se stránka reloadne, ale obsah metody „formSucceeded“ se neprovede.
Editoval dubblen (19. 8. 2016 16:43)
- dubblen
- Člen | 9
uestla napsal(a):
@dubblen Zkusil jsem vykreslit recaptchu pomocí
n:name
a vše funguje. Hlásí to chybu v konzoli i po @GEpic ově úpravě?Používáš form nějak „nestandardně“ (vykresluješ vícekrát na jedné stránce, AJAX, …)?
Vykresluju už pomocí {input recaptcha}, ale pořád žádná změna. Chybu v JS consoli jsem již vyřešil. V templatě jsem importoval recaptcha.js 2× (zbytky z některého z pokusů v minulosti). Každopádně na celkové (ne)funkčnosti to nic nezměnilo. Když v továrničce odmažu řádek s addReCpatcha, tak vše funguje. Ale bez ReCaptchy…
Editoval dubblen (21. 8. 2016 17:26)
- GEpic
- Člen | 566
dubblen napsal(a):
uestla napsal(a):
@dubblen Zkusil jsem vykreslit recaptchu pomocí
n:name
a vše funguje. Hlásí to chybu v konzoli i po @GEpic ově úpravě?Používáš form nějak „nestandardně“ (vykresluješ vícekrát na jedné stránce, AJAX, …)?
Vykresluju už pomocí {input recaptcha}, ale pořád žádná změna. Chybu v JS consoli jsem již vyřešil. V templatě jsem importoval recaptcha.js 2× (zbytky z některého z pokusů v minulosti). Každopádně na celkové (ne)funkčnosti to nic nezměnilo. Když v továrničce odmažu řádek s addReCpatcha, tak vše funguje. Ale bez ReCaptchy…
No já měl taky problém ten, že jsem musel importovat skript v hlavičce <head>, namísto v patičce stránek, jako je to s ostatními JS.
- dubblen
- Člen | 9
Tohle je tracy dump requestu z presenteru. Pro jistotu recaptcha.js načítám taky už v <head>. Stále bez úspěchu. Po kliknutí na „Odeslat“ se stránka pouze refreshne, ale nic se neprovede.
Nette\Http\Request #9071
method private => "POST" (4)
url private => Nette\Http\UrlScript #0813
post private => array (6)
nickname => "Jméno " (7)
email => "info@mail.com" (13)
headline => "Nadpis " (7)
text => "asdasdasd" (9)
send => "Odeslat" (7)
"g-recaptcha-response" => "03AHJ_VusdsQQeBGb8Kq5XjjnHrrzV2YH_Dvqfscu-iPpI0rIWC1OoQibqLMnXFKz20renoZEzUb87AU55362WdOuIfx5IWrhbkhx1sLT6B2mxGIC2N73fodxmg18yukzzuLfsKInw6Q-UmIybB1Eh ... " (1230)
files private => array ()
cookies private => array (2)
PHPSESSID => "6ia94ea9e4bdfe8s6iqkrfp336" (26)
"nette-browser" => "kvxnrnrkoz" (10)
headers private => array (12)
remoteAddress private => "::1" (3)
remoteHost private => NULL
rawBodyCallback private => Closure #0725
file => "/vendor/nette/http/src/Http/RequestFactory.php" (81)
line => 273
variables => array ()
parameters => ""
- GEpic
- Člen | 566
dubblen napsal(a):
Tohle je tracy dump requestu z presenteru. Pro jistotu recaptcha.js načítám taky už v <head>. Stále bez úspěchu. Po kliknutí na „Odeslat“ se stránka pouze refreshne, ale nic se neprovede.
Nette\Http\Request #9071 method private => "POST" (4) url private => Nette\Http\UrlScript #0813 post private => array (6) nickname => "Jméno " (7) email => "info@mail.com" (13) headline => "Nadpis " (7) text => "asdasdasd" (9) send => "Odeslat" (7) "g-recaptcha-response" => "03AHJ_VusdsQQeBGb8Kq5XjjnHrrzV2YH_Dvqfscu-iPpI0rIWC1OoQibqLMnXFKz20renoZEzUb87AU55362WdOuIfx5IWrhbkhx1sLT6B2mxGIC2N73fodxmg18yukzzuLfsKInw6Q-UmIybB1Eh ... " (1230) files private => array () cookies private => array (2) PHPSESSID => "6ia94ea9e4bdfe8s6iqkrfp336" (26) "nette-browser" => "kvxnrnrkoz" (10) headers private => array (12) remoteAddress private => "::1" (3) remoteHost private => NULL rawBodyCallback private => Closure #0725 file => "/vendor/nette/http/src/Http/RequestFactory.php" (81) line => 273 variables => array () parameters => ""
No a když přidáš k formuláři událost onError a
zkusíš dumpnout $form->getErrors()
?
PS: Taky se mrkni jestli máš poslední verzi reCaptchy.
Editoval GEpic (21. 8. 2016 20:14)
- dubblen
- Člen | 9
GEpic napsal(a):
dubblen napsal(a):
Tohle je tracy dump requestu z presenteru. Pro jistotu recaptcha.js načítám taky už v <head>. Stále bez úspěchu. Po kliknutí na „Odeslat“ se stránka pouze refreshne, ale nic se neprovede.
Nette\Http\Request #9071 method private => "POST" (4) url private => Nette\Http\UrlScript #0813 post private => array (6) nickname => "Jméno " (7) email => "info@mail.com" (13) headline => "Nadpis " (7) text => "asdasdasd" (9) send => "Odeslat" (7) "g-recaptcha-response" => "03AHJ_VusdsQQeBGb8Kq5XjjnHrrzV2YH_Dvqfscu-iPpI0rIWC1OoQibqLMnXFKz20renoZEzUb87AU55362WdOuIfx5IWrhbkhx1sLT6B2mxGIC2N73fodxmg18yukzzuLfsKInw6Q-UmIybB1Eh ... " (1230) files private => array () cookies private => array (2) PHPSESSID => "6ia94ea9e4bdfe8s6iqkrfp336" (26) "nette-browser" => "kvxnrnrkoz" (10) headers private => array (12) remoteAddress private => "::1" (3) remoteHost private => NULL rawBodyCallback private => Closure #0725 file => "/vendor/nette/http/src/Http/RequestFactory.php" (81) line => 273 variables => array () parameters => ""
No a když přidáš k formuláři událost onError a zkusíš dumpnout
$form->getErrors()
?PS: Taky se mrkni jestli máš poslední verzi reCaptchy.
Vypíše tohle:
array (1)
0 => "Please prove you're not a robot." (32)
Recaptchu ale zaškrtávám.
Mám poslední verzi reCaptchy.
Editoval dubblen (21. 8. 2016 21:30)
- dubblen
- Člen | 9
uestla napsal(a):
Chyby formuláře tedy v šabloně nevypisuješ. Máš správně nastavený siteKey a secretKey? Máš povolenou doménu, na které reCAPTCHu používáš (localhost by měl jít automaticky)?
siteKey i secretKey mám zapsaný správně. Vyvíjím lokálně. I tak mám pro jistotu localhost přidaný.
Editoval dubblen (21. 8. 2016 23:48)