I have this code in my form:
<div class="g-recaptcha" data-sitekey="MY_KEY"></div>
And the validation part:
// Re captcha part
if (isset($_POST['g-recaptcha-response'])){
$captcha = $_POST['g-recaptcha-response'];
}
if (!$captcha) {
redirect('login', 'refresh');
}
$response=file_get_contents("https://www.google.com/recaptcha/api/siteverify?secret=MY_SECRET_KEY&response=".$captcha."&remoteip=".$_SERVER['REMOTE_ADDR']);
// t($response,1);
if($response."success" == false) {
redirect('login', 'refresh');
}
It sort of works now, this is my result:
When I click the checkbox, I still need to type the text for verification.
I thought that clicking the checkbox was enough?
Am I doing something wrong here?
Here's how I check "No Captcha" response and it always shows me "one click" verification box, even in localhost:
$g_recaptcha_response = filter_input(INPUT_POST, 'g-recaptcha-response');
if (isset($g_recaptcha_response)) {
$google = 'https://www.google.com/recaptcha/api/siteverify?secret='
. ZorAuthConfig::RC_SECRET_KEY
. '&response=' . $g_recaptcha_response;
$google_json = file_get_contents($google);
$google_data = json_decode($google_json);
// Check reCaptcha response.
if (!$google_data->success) {
// Do something if robot.
} else {
// Do something if human.
}
}
I implemented this in small library I wrote recently, so you can check it out if you want more details: https://github.com/zoran-petrovic-87/ZorAuth
http://zoran87.blogspot.com/2014/12/zorauth-10b-complete-flexible-no.html
The reCaptcha will verify at first if you are a bot or not by analyzing your mouse movements (and other stuff).
In case the test failed, it will popup a box where you need to write the 2 words shown in the image.
This is all fine and normal, but this is only a client side validation, if you need to make sure that validation was truly successful and not hacked in some way, or whatever... Then you submit the form which will contain the g-recaptcha-response like the way you did, then you will receive the final confirmation from Google in that JSON string.
Related
I have a form and I don't do client-side validation other than required attribute. I'm doing the validation on the server side.
lyrics/add.php
<form action="../scripts/lyrics/submit_lyrics.php" id="lyricsForm" method="post" autocomplete="off" enctype="multipart/form-data">
Form data is processed in a seperate php file. Retrieving and validating the form data in the following way:
scripts/lyrics/submit_lyrics.php
$form_data = new FormData(["artist", "album", "song", "year", "track_no", "lyrics"], "sssiis");
$form_data->validate();
What the validate method does is
public function validate() {
$valid = $this->check_form_data($fields);
$fields = implode(",", $fields);
if (!$valid) {
header("location: ".BASE."lyrics/add?status=error&problem=input&specifics=$fields");
exit;
}
}
check the form data and redirect the page (scripts/lyrics/submit_lyrics.php) to the form page (lyrics/add.php) with the information on validation (if it failed). Then I output an error message indicating that there's something wrong with the input using GET method.
I'm curious if I can do this using POST. I would need to modify this line
header("location: ".BASE."lyrics/add?status=error&problem=input&specifics=$fields");
make it redirect the page to BASE."lyrics/add" and also send the validation information using POST to that page. So I'd still be able output the validation error, but using POST instead of GET.
Is this possible?
No, this is not possible because you are rewriting the request. The browser will always send a "GET" request in response to a redirect request, unless it receives a 307 request in which it will repeat the request using the same method and parameters. See this related question on Programmers.
The workaround is to redirect to a new page with an embedded form that you generate, and have javascript POST that form for the user. It's an extra request but it's the only way to have the client make a second POST.
Using u_mulder's suggesion (storing values in a session), I've solved the problem in the following way:
scripts/lyrics/submit_lyrics.php
public function validate() {
$valid = $this->check_form_data($fields); // check if input fields are valid
$fields = implode(";", $fields); // invalid input fields
if (!$valid) { // not all fields are valid, so we return
session_start(); // start session
if (!isset($_SESSION["problem"])) { // making sure session variable doesn't exist
$_SESSION["problem"] = "input"; // error type: input, file_upload, db_insert, etc.
$_SESSION["specifics"] = $fields; // artist, album, etc. (for input)
}
header("location: ".BASE."lyrics/add?status=error"); // redirect to form page
exit;
}
}
lyrics/add.php
if (isset($_GET["status"])) {
$status = $_GET["status"];
switch ($status) {
case "error":
session_start();
if (isset($_SESSION["problem"])) {
$problem = $_SESSION["problem"];
$specifics = explode(";", $_SESSION["specifics"]);
$error_message = "There was an error.";
switch ($problem) {
case "input":
$error_message = "Invalid input on the following fields:";
break;
// other cases ...
}
session_destroy();
output("Error!", $error_message, $specifics);
} else {
// if the user reloads the page, session data is lost
// but we're still in the error page "lyrics/add?status=error" and have no error to show
// we either show an appropriate message or redirect to "lyrics/add"
session_destroy();
// output("Error!", "You're in the form validation error page, but there aren't any errors. Did you reload the page?");
// header("location: ".BASE."lyrics/add");
// exit;
}
break;
case "success":
// form submitted successfully
break;
}
} else {
// show form
}
I'm experiencing a very odd problem. Everything works as expected on my local host. When I upload to a live server, the page just cuts off right where I'm including a file. Just white space beneath it. Nada...
The line that breaks is:
<? require_once('inc/store-address.php'); if($_GET['submit']){ echo storeAddress(); } ?>
And the file being included is:
<?php
/*///////////////////////////////////////////////////////////////////////
Part of the code from the book
Building Findable Websites: Web Standards, SEO, and Beyond
by Aarron Walter (aarron#buildingfindablewebsites.com)
http://buildingfindablewebsites.com
Distrbuted under Creative Commons license
http://creativecommons.org/licenses/by-sa/3.0/us/
///////////////////////////////////////////////////////////////////////*/
function storeAddress(){
// Validation
if(!$_GET['email']){ return "No email address provided"; }
if(!preg_match("/^[_a-z0-9-]+(\.[_a-z0-9-]+)*#[a-z0-9-]+(\.[a-z0-9-]+)*$/i", $_GET['email'])) {
return "Email address is invalid";
}
require_once('MCAPI.class.php');
// grab an API Key from http://admin.mailchimp.com/account/api/
$api = new MCAPI('xxxxxxx');
// grab your List's Unique Id by going to http://admin.mailchimp.com/lists/
// Click the "settings" link for the list - the Unique Id is at the bottom of that page.
$list_id = "xxxxxx";
if($api->listSubscribe($list_id, $_GET['email']) === true) {
// It worked!
// return 'Success! Thank You!';
echo '<script> window.location.href = "thank-you.php"; </script>';
}
else
{
// An error ocurred, return error message
return 'Error: ' . $api->errorMessage;
}
}
// If being called via ajax, autorun the function
if($_GET['ajax']){ echo storeAddress(); }
?>
The only thing edited in the above code is the API key and List ID.
its because is missing parentesis on your if condition.
require_once('inc/store-address.php');
if($_GET['submit'] **)** {
echo storeAddress();
}
It seems there was an error. It was working on my local server because there wasn't an error.
I was using filezilla do upload my content. For some reason it appears to be an encoding issue when uploading.
I don't know if I should delete this question or answer to help someone else with the problem later on so I chose the later.
I manually uploaded my file and guess what, it works!
Hi i have a multi step form , so far so good it is validated with java and php , but what i need yet is to disable the user going back after submitting .
So this mean i want to stop or to erase the filled fields if the user click back from the redictet page after submitting my form
i have read somthing about a hidden token input over but i dont know how to implement it for my needs .
So here is my proces.php this :
$emotion = $_POST['emotion'];
if($emotion == 'Basic Pack') {
session_start();
$_SESSION['form_finished'] = true;
header('Location: /new/basicc.php');
} elseif($emotion == 'Deluxe Pack') {
header('Location: html6.php');
} elseif($emotion == 'Premium Pack') {
header('Location: html7.php');
}
in the destination page this case basicc.php this
<?php
session_start();
if(!$_SESSION['form_finished']) {
header("HTTP/1.0 404 Not Found");
exit;
}
?>
How can i stop my user to go back or direct him to a error or at least delete his filled fields if he chose to go back after submitting ?
any help would be welcomed . thanks in advance
Here's my setup for an email contact form:
www.example.com/includes/contact_form.php
www.example.com/includes/contact_submit.php
www.example.com/contact/
/contact/ includes contact_form.php, and the form points to contact_submit.php to run.
When contact_submit.php successfully sends the mail, it does a redirect back to /contact/ but includes a $_GET variable.
header('Location: /contact/index.php?success=yup');
Then in contact_form.php I have:
if (isset($_GET['success'])) { echo 'Your message has been received etc'; exit(); }
Everything works fine. I made it this way so that the form couldn't be F5/refresh resubmitted, and it is successful in that.
However, anyone can access the success page at any time by manually entering the url, even if they don't submit the form. Is there any way around that?
Ofcourse.
Use sessions for that:
class ResponseLog {
private function __construct(){}
public static function hasMessages(){
return (isset($_SESSION['response']['messages']) && !empty($_SESSION['response']['messages'])) ? true : false;
}
public static function setResponse(array $response){
$_SESSION['response'] = $response;
}
public static function getLastResponse(){
$response = isset($_SESSION['response'])) ? $_SESSION['response'] : null;
#unset($_SESSION['response']);
return $response;
}
}
And use it like this:
if(isset($_POST['form'])){
//validation and all to proccess request goes here
if(!$valid){
$response = array('request' => $_POST,'messages' => array('Incorrect email','Please enter forename'),'url' => '/my/form/where/it/happen/');
}
else {
$response = array('messages' => array('Success'),'url' => '/my/form/where/it/happen/');
}
ResponseLog::setResponse($response);
//redirect to contact form
}
In success page or fail:
if(ResponseLog::hasMessages()){
$response = ResponseLog::getLastResponse();
foreach($response['messages'] as $message){
echo $message;
}
}
With this you can store everything user does and can work with data as you need.
I hope this help :)
Warn: I wrote it from mind, so it's untested code and it can be implemented better it's just for view how to work with user session and responses.
PS: But is a lot of ways how to do it, for example see flash messages in some framework and you will be see how it works with sessions etc.
You can use the referrer page if you want, and throw an error or redirect if it is not the form page, but it is not so good. You can also check whether the fields and form name have been posted.
$_SERVER['HTTP_REFERER']
I have a form on a php page that is submitted to the same page.
I noticed that if I reload/refresh the page the form gets re-submitted.
How do I code to avoid this in the most easy way?
One possibility is, to implement the post-redirect-get approach.
Simply said, a POST request will be never delivered to the browser. Instead you execute all necessary actions and store the information you need in the session, and then you make a redirect with code 303.
$page = 'show_result.php';
header('Location: '.$page, true, 303);
exit;
Doing it this way, the browser will show the "show_result.php" page (a GET request) instead of the page requested with POST. This is also the page that is added to the history, so refreshing and using the back button will never do another POST request. As a nice side effect you get rid of browser warnings about resending data, normally the user cannot decide what to do then anyway.
I think the biggest problem with this approach is, that you need a session to store error messages, that means you have to rely on cookies. If you do no redirect to display errors, the browser will show the warning about resending data.
This assume a lot of things, but maybe is what you are looking for:
if ($_POST)
{
$success = false;
/*
* if all goes OK managing POST data make $success = true;
*
*/
if ($success)
{
// this will redirects to your original
// form's page but using GET method
// so re-submitting will be no possible
header("location: {$_SERVER['PHP_SELF']}");
exit;
}
}
According to HTTP standard, you ought to make browser to do a GET request after sending POST one.
Here is a sketch example to do the form handling:
<?
if ($_SERVER['REQUEST_METHOD']=='POST') {
$err = array();
//performing all validations and raising corresponding errors
if (empty($_POST['name']) $err[] = "Username field is required";
if (empty($_POST['text']) $err[] = "Comments field is required";
if (!$err) {
//if no errors - saving data and redirect
header("Location: ".$_SERVER['PHP_SELF']);
exit;
} else {
// all field values should be escaped according to HTML standard
foreach ($_POST as $key => $val) {
$form[$key] = htmlspecialchars($val);
}
} else {
$form['name'] = $form['comments'] = '';
}
include 'form.tpl.php';
?>