Google reCAPTCHA g-recpatcha-response has no value in PHP - php

p.s: I gave up on this as I found no solution and implemented my own php captcha that worked a treat :) - http://www.the-art-of-web.com/php/captcha/
I have spent many hours & days trying to solve this problem but I cannot seem to figure it out. I have read a lot of different tutorials & questions online.
Just to keep in mind, my PHP level is fairly basic.
I cannot seem to get the 'g-recaptcha-response' $_POST value in my php file.
I have summarised the important code needed below...
File 1: contact.php
Before Head Tags
<?php
session_start(); // start php session
// Setup session variables to save the form data
if( isset($_SESSION['contact_form_values']) ){
extract( $_SESSION['contact_form_values'] );
}
include('contactengine.php');
?>
In Head Tags
<script src='https://www.google.com/recaptcha/api.js'></script><!-- reCAPTCHA form -->
Between the Form tags
Action="" so that it posts to itself which has the contactengine.php file included so that it runs through only when the user clicks the submit button?
<form class="contactform" method="POST" action="">
<div class="g-recaptcha" data-sitekey="6Lc92gkTAAAAAFKjZEOlY0cg9G8ubmlVoC13Xf3T"></div>
File 2: contactengine.php
Between this
if($_SERVER["REQUEST_METHOD"] == "POST")
I have
if( isset( $_POST['g-recaptcha-response'] ) ){
$captchaResponse = $_POST['g-recaptcha-response'];
}
Now this is the point where the variable $captchaResponse isn't being populated as I output the value of it like this:
if( !$captchaResponse ){ // check the POST recaptcha response value
$resultMsg = 'Please check the captcha form. - '.$captchaResponse;
}
Therefore I get no visible output of the response code in the $resultMsg string.
The only thing I could think is effecting it, is including the contactengine.php file at the beginning in contact.php. And having the action as ="". But this is what the tutorial guided me to do. So maybe not...
I used http://www.9lessons.info/2014/12/google-new-recaptcha-using-php-are-you.html as the guide.
Thanks a lot in advanced!

You're nearly there! You just need to query Google's API.
if (isset($_POST['g-recaptcha-response'])) {
$captcha = $_POST['g-recaptcha-response'];
}
if (!$captcha) {
// Captcha wasn't checked, do something...
exit;
}
$response = file_get_contents("https://www.google.com/recaptcha/api/siteverify?secret=SECRETKEYGOESHERE&response=".$captcha."&remoteip=".$_SERVER['REMOTE_ADDR']);
if ($response.success == false) {
// Captcha failed! Do something!
} else {
// Captcha is valid! Do something else!
}
Replace SECRETKEYGOESHERE with your actual secret key, and you're set!

Related

Display alert box upon form submission

So I have these two pages: pageOne.php and pageTwo.php.The form is in pageOne.php:
<form method="post" action="pageTwo.php"> .... </form>
and doing all the data collection-validation-insertion and sending out mails in pageTwo.php (the reason i'm doing everything in two separate pages is to avoid the data re-submission upon page refresh...this was the easiest way for me to handle the issue). So far everything is working perfectly.
Now, I want to display a success/failure message using alert box after the form submission and tried few things w/o any luck. E.g. when I tried THIS solution on pageTwo.php, no pop up box shows up and I think that's because I have this header on top of that page
<?php header("Location: http://TestPages.com/pageOne.php"); ?>
<?php
if( $_POST ) {
//collect the data
//insert the data into DB
//send out the mails IFF the data insertion works
echo "<script type='text/javascript'>alert('It worked!')</script>";
}else
echo "<script type='text/javascript'>alert('Did NOT work')</script>";
?>
And when tried this second solution in pageOne.php, I get the alert box popping up every time i refresh the page and get the failure message even though the data had been inserted into database and mails were sent out. pageOne.php:
<html>
<body>
<?php
if( $GLOBALS["posted"]) //if($posted)
echo "<script type='text/javascript'>alert('It worked!')</script>";
else
echo "<script type='text/javascript'>alert('Did NOT work')</script>";
?>
<form method="post" action="pageTwo.php"> .... </form>
</body>
and in pageTwo.php:
<?php header("Location: http://TestPages.com/pageOne.php"); ?>
<?php
$posted = false;
if( $_POST ) {
$posted = true;
//collect the data
//insert the data into DB
//send out the mails IFF the data insertion works
} ?>
Why isn't this simple thing working :( ? is there any easy way to fix it? Thank you!!
UPDATE
So I have made some changes according to drrcknlsn's sugession and this is what I have so far....pageOne.php:
<?php
session_start();
if (isset($_SESSION['posted']) && $_SESSION['posted']) {
unset($_SESSION['posted']);
// the form was posted - do something here
echo "<script type='text/javascript'>alert('It worked!')</script>";
} else
echo "<script type='text/javascript'>alert('Did NOT work')</script>";
?>
<html> <body>
<form method="post" action="pageTwo.php"> .... </form>
</body> </html>
and pageTwo.php:
<?php
session_start();
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
$_SESSION['posted'] = true;
//collect the data
//insert the data into DB
//send out the mails IFF the data insertion works
header('Location: http://TestPages.com/pageOne.php');
exit;
} ?>
With these changes now the page's redirection and success message is working, but i get the failure msg every time i open/refresh the page (i know that's because the session key is not set yet)...how can i avoid that? Thanks again!!
First, a couple points:
Variables (even globals) are not shared across requests like you're trying to do in your bottom example. In order for $posted to be accessible in both pages, you must persist it in some way. Usually this involves setting a session variable (e.g. $_SESSION['posted'] = true;), but it could also be persisted in a cookie, in a database, on the filesystem, in a cache, etc.
Use something like if ($_SERVER['REQUEST_METHOD'] === 'POST') instead of if ($_POST). While the latter is probably safe in most cases, it's better to get in the habit of using the former because there exists an edge case where $_POST can be empty with a valid POST request, and it may be a hard bug to track down.
One potential pattern to solve your problem using the above advice:
pageOne.php:
<?php
session_start();
if (isset($_SESSION['posted']) && $_SESSION['posted']) {
unset($_SESSION['posted']);
// the form was posted - do something here
}
?>
...
<form>...</form>
pageTwo.php:
<?php
session_start();
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
$_SESSION['posted'] = true;
// do form processing stuff here
header('Location: pageOne.php');
exit;
}
// show an error page here (users shouldn't ever see it, unless they're snooping around)
It looks like it's a scope problem.
use:
global $posted = true;
http://php.net/manual/en/language.variables.scope.php

ModX custom package xPDO statement not evaluating correctly

I'm developing a custom package that accepts a form input, compares it against a table and display the relevant information on the screen, I have the transport and schema setup correctly (I hope! I followed the guide at BobsGuides.com) and I can read back from the table without issue. My problems began when I started implementing the form input.
Basically the session variables I am posting never seem to get recieved so the isset never evaluates to true and I just see the form over and over again.
I've only just begun with PHP and am a complete newb when it comes to xPDO so I accept theres probably more than a few things I havn't noticed but if someone could point me in the right direction I'd be extremely grateful.
<?php
$path = MODX_CORE_PATH . 'components/dataease/';
var_dump($_POST['submit']);
var_dump($_POST['accNo']);
// get POST variable this is captured
$accNo = $_POST['accNo'];
$output = '';
// Check if form has been submitted
if (isset($_POST['submit'])) {
// Get info from the database
$query = $modx->newQuery('accno');
$query->select($modx->getSelectColumns('Dataease','Dataease','',array('*')));
$query->where(array('accNumber:LIKE' => '$accNo'));
var_dump($query);
// Place it into a variable for output
if (!$query) {
return "Query failed";
} else {
$dataease = $modx->getCollection('Dataease',$query);
// Count the returned rows, should only ever be 1
$output .= '<p>Total: '. count($dataease) . '</p>';
// Show the found data
foreach($dataease as $sql) {
$fields = $sql->toArray();
$output .= $modx->getChunk('showData', $fields);
}
}
return $output;
} else {
// Get the form chunk
$form = $modx->getChunk('dataEntryForm');
return $form;
}
This is my form chunk
<h2>Enter Account Number:</h2>
<form method="POST" action="">
<input name="accNo" type="text"/>
<input name="submit" type="submit" value="submit" />
</form>
Give this a try to see if there has been a post submission
if($_SERVER['REQUEST_METHOD'] == "POST")
and/or give your form a hidden submit field, some browsers [at least some used to] not post the submit field if you just hit return when the submit button is not in focus. Test for that as well.
Do you trying http://rtfm.modx.com/display/ADDON/Rowboat for work with your tables?

Passing php form validate error message back to submit form

I'm trying to pass an error message from a server side form validator in a function back to the form it was submitted in. The validator is working as it prevents the rest of the code saving it to a database as planned. However I cant get it to pass back to the form to display the error
function saveComment(){
$validate = array();
$id = isset($_POST["articleId"]) ? $_POST["articleId"] : '';
if ( isset( $_POST['saveChanges'] ) ) {
if ( $_POST['name'] == "" ){
$validate['errorMessage'] = "Please fill out your name.";
header( "Location:".HOME_PATH."/.?action=viewArticle&articleId=".$_POST['articleID']."");
}
I' trying to pass it back to this
if ( isset( $validate['errorMessage'] ) ) {
echo $validate['errorMessage'];
}
When I remove the if on the display function I get the error unidentified index
What do I need to do to get the form to display the error message. Do I need to pass the array to the function that handles the display of the article?
FEEDBACK
For anyone that may find this useful I used #OliverBS post method pretty much unaltered.
Also thank you to #lethal-guitar as he explanation has helped me understand where I went wrong and the various methods that can be used to solve this problem +1
You're setting a variable $validate for your currently executing script. Afterwards, you send a redirect header. This will cause your browser to issue a new request, thus ending the currently executing script and scrapping the variable. The new request will trigger another script invocation, where the variable is not known anymore since it only existed for the duration of the first request.
HTTP is stateless, so every variable you set on the server side will only exist until you finish your current request and respond to the client. What you need is a way to pass this variable to the script handling the second request. There are several ways to do so:
Pass a GET parameter. You could append something like "&validationError=" . $validate['errorMessage'] to the URL you're passing to the Location header, and then in the display page access it via $_GET.
Save the validation status in the $_SESSION. The PHP manual contains a lot of information about sessions (maybe you're already using them?)
Restructure your code in a way that you don't redirect on error, but on success.
Some more information on the 3rd proposal: You write one PHP-Script which displays the form and handles the form post request. If validation fails, you simply redisplay, and insert the echo statement you already have. If it suceeds, you redirect to some success page. This way, the variable will remain accessible, since it's still the same request.
On a quick glance try this
Session way
Make sure to start the session by doing session_start(); at the top of the file where saveComment is and the isset checked.
function saveComment(){
$id = isset($_POST["articleId"]) ? $_POST["articleId"] : '';
if ( isset( $_POST['saveChanges'] ) ) {
if ( $_POST['name'] == "" ){
$_SESSION['errorMessage'] = "Please fill out your name.";
header( "Location:".HOME_PATH."/.?action=viewArticle&articleId=".$_POST['articleID']."");
}
if ( isset( $_SESSION['errorMessage'] ) ) {
echo $_SESSION['errorMessage'];
}
or you can try
POST way
function saveComment(){
$id = isset($_POST["articleId"]) ? $_POST["articleId"] : '';
if ( isset( $_POST['saveChanges'] ) ) {
if ( $_POST['name'] == "" ){
$error = urlencode('Please fill out your name');
header( "Location:".HOME_PATH."/.?action=viewArticle&articleId=".$_POST['articleID']. "&error=" . $error);
}
if ( isset( $_GET['error'] ) ) {
echo urldecode($_GET['error']);
}
I have not tested this but you should get the basic idea of what to do.
When you do a header location your redirecting the user to a new page. Your going to have to either pass the error in the query string or ideally pass it as a variable in the session.
I would suggest doing this all in one file, i.e. The form and the validation as one file.
Then you can do this:
<?php
//set success to 0
$success = 0;
$errormsgs = array();
//check for post
if(isset($_POST['submit'])){
//get the data from the form post and validate it
$valid = validateFuntion($_POST['data'])
//the is function will validate the data. If it is not valid, it will add a message to $errormsgs
//check for errors
if(!$errormsgs){
//data validation was successful, do stuff
}
}//if validation fails, it will fall out of the this code block and move on
?>
<html>
<body>
<?php
//check for errors
if($errormsgs){
$content .= '<ul class="errors">';
foreach($errormsgs as $error){
$content .= "<li>" . $error . "</li>";
}
$content .= "</ul>";
echo $content;
}
?>
<form name="name" action="" method="post">
<input name="name" value="<?= (isset($_POST['data']) ? $_POST['data'] : '') ?>" type="text">
</form>
</body>
</html>
You're redirecting the user to the "error" page with the header statement. The problem is, of course, this is a completely new page, there's no state left over, so none of your variables exist any more.
There's two ways to do it, either pass it on the query string (so add &error=...) and parse that in your template, or save it to the session.
Of course, you should really be doing this before your template is presented using a different means, but that's a complete rework of your code.

Persistent flag that user is on facebook?

I'm in the middle of designing a mobile site for our main ecommerce site. Because the site is composed of inflexible legacy code I've opted to look up the users user agent string and identify them as a mobile user each page request. That way no changes to the url structure are needed. This seems to be working nicely so far.
However, I thought it may be kind of cool to use this mobile version so that users can browse our ecommerce site on facebook via iframe (the dimensions are perfect). But, unlike the mobile browsers, I am having trouble finding a persistent way to identify the user as a facebook user. I know facebook sends a $_POST variable the first time a page is viewed via iframe, and I could simply just store that in a session variable and be done with it. The issue that arises though is that what if the user visits with facebook, gets marked as a facebook user in their session, then visits our regular ecommerce site? Well, they'd still be identified as a facebook user and get served the facebook version, which is not ideal.
Maybe you can tackle the problem for another angle and test if the website is loaded from a frame or not?
This is possible with javascript:
if (top === self) {
//not a frame
} else {
//a frame
}
Not sure if it's proper etiquette to answer my own question but I found an answer which is a combo of Hassou's answer and a javascript php detection script.
The script I altered is from here:
http://snippets.bluejon.co.uk/check4-js-and-cookies/check4-js-enabled-v2-phpcode.php
Essentially the idea is to use javascript to submit a form referencing the current url, the result tells you if javascript is enabled... However, the idea can easily be altered to submit a form only if javascript returns true for being in an iframe. You can then pass in the $_POST data into the form so that the $_POST data is carried over (only needed if the $_POST data is referenced within the display layer of your application). Here's the basic idea:
<?php
/* Include head of your application goes here, this should do whatever
session handling code you have and all processing done to the $_POST variables */
// ~~~~~~Full Url Function - Works With Mod_Rewrite~~~~~~~~~ //
// important thing is function will grab all $_GET vars
function fullurlnav()
{
$fullurlsortnav = 'http';
$script_name = '';
if(isset($_SERVER['REQUEST_URI']))
{
$script_name = $_SERVER['REQUEST_URI'];
}
else
{
$script_name = $_SERVER['PHP_SELF'];
if($_SERVER['QUERY_STRING']>' ')
{
$script_name .= '?'.$_SERVER['QUERY_STRING'];
}
}
if(isset($_SERVER['HTTPS']) && $_SERVER['HTTPS']=='on')
{
$fullurlsortnav .= 's';
}
$fullurlsortnav .= '://';
if($_SERVER['SERVER_PORT']!='80')
{
$fullurlsortnav .=
$_SERVER['HTTP_HOST'].':'.$_SERVER['SERVER_PORT'].$script_name;
}
else
{
$fullurlsortnav .= $_SERVER['HTTP_HOST'].$script_name;
}
return $fullurlsortnav;
}
// ~~~~~~~~~~~End Full URL Function~~~~~~~~~ //
?>
<html>
<body>
<?php
// Only run this check if user has been identified as a facebook user in their session
// or if they've been identified via the $_POST['signed_request'], which facebook sends
// upon first request via iframe.
// Doing this removes the check when it's unneeded.
if (!isset($_POST['inIframe']) && ( isset($_SESSION['inIframe']) || isset($_POST['signed_request']) ) )
{
?>
<form name="postJs" action="<?php echo fullurlnav(); ?>" method="post">
<input type="hidden" name="inIframe" value="1">
<?php
// Carry over $_POST
foreach($_POST as $key => $value)
{
echo '<input type="hidden" value="'.$value.'" name="'.$key.'" />';
}
?>
</form>
<script type="text/javascript">
<!--
// If in an iframe
if (top !== self)
{
document.postJs.submit();
}
//-->
</script>
<?php
}
elseif(isset($_POST['inIframe']) && ( isset($_SESSION['inIframe']) || isset($_POST['signed_request']) ) )
{
$_SESSION['inIframe']=1;
}
else
{
$_SESSION['inIframe']=0;
}
if ($_SESSION['inIframe']== 1){
echo 'IS in an Iframe';
}else{
echo 'IS NOT in an Iframe';
}
// echo out rest of your template code
?>
</body>
</html>
It gets a little tricky skating around your page display code output and it's workings, but that's the basic idea i have so far. Technically one could separate the form generation block from the elseif else statements below, and use those above your code before any display output, that may be easier to handle. Note that the above code is untested, just given to provide the basic idea for others with the same issue.

How to check if a text area 'contains' a certain phrase with javascript / php?

I'm trying to work out how to go about checking a text area to see if it contains a certain phrase.
I believe I could maybe use .indexOf?
It's just I have a validation script to check the contents of a contact form. Lately I have been receiving a fair bit of spam through. I have noticed that all these spam messages contain the phrase [url= and I thought, if I could perhaps add a small script to check if the text area contained such a phrase and, if so, stop the message being sent.
At present I have this simple snippet of javascript to check whether the text area is blank:
if (message.val()=='') {
message.addClass('highlight');
message.focus();
return false;
} else message.removeClass('highlight');
Any good ways to add something to check if the message field contains [url=
I also have a similar php validation script:
if (!$message) $errors[count($errors)] = 'Please click back and enter your message.';
Any ideas how I could add a similar validation script to check if message contains [url= in php too?
Any help would be greatly appreciated! :o)
It's unlikely that you'll stop spam by checking the contents of your textarea at the client side:- the spammer is more than likely POSTing directly to your server side script, so you'll need to do your filtering there. Also checking for a particular pattern will only work until the pattern changes and then you'll have to update your script.
A common solution to this problem is the use of a One-Time Form Token.
When you serve the form you generate a random string of characters and place that token in a hidden field in the form. You also store the token on the server in a session or in a database. When the form is submitted you match the stored and submitted tokens. This way you can be more sure that the form itself was filled in and submitted and that you aren't receiving data from a bot.
For extra security you can only allow each token to be used once only, guarding against multiple submissions.
UPDATE
A very simple, one page example
<?php
session_start();
/**
* Process the form if we have a token that we recognise
* otherwise just present the form again, you probably want to handle this a bit better
*/
if( isset( $_POST['token'] ) && isset( $_SESSION['token'] )
&& $_POST['token'] === $_SESSION['token'] ) {
// no more submissions using this token
unset( $_SESSION['token'] );
$name = clean( $_POST['name'] );
$comment = clean( $_POST['comment'] );
// process the input and redirect to a confirmation
// just echoing data for example
echo "$name said $comment";
die();
} else {
$token = uniqid();
$_SESSION['token'] = $token;
}
/**
* Stub function that cleans user input
* #param String $str
*/
function clean( $str ) {
return $str;
}
?>
<html>
<head>
<title>Form token example</title>
</head>
<body>
<form method="post">
<label>
Name<br/>
<input type="text" name="name"/>
</label>
<br/>
<label>
Comment<br/>
<textarea name="comment"></textarea>
</label>
<br/>
<label>
<input type="submit"/>
</label>
<br/>
<br/>
The token field would normally be hidden, it's displayed here so that the user can change it for testing<br/>
<input type="text" name="token" value="<?php echo $token ?>"/><br/>
</form>
</body>
</html>
check out the javascript search method and javascript match method. I prefer search becuase if you only care if it does exist then you do something like this.
var stringToSearch = "stackoverflow";
if (stringToSearch.search("over") >= 0){
//exists
}
By the way your question didn't do something right. I don't know php so i can't help you there
message.val().match('your phrase here')

Categories