I am using 2checkout payment gateway in my PHP project and facing issue in generating token with 'sandbox' mode. Here's the code:
<form action="" method="post" id="frmSignup" name="frmSignup">
<input type="hidden" value="" name="token" id="token" />
<script type="text/javascript" src="https://www.2checkout.com/checkout/api/2co.min.js"></script>
<script>
// Called when token created successfully.
var successCallback = function(data) {
console.log("success::"+data);
var myForm = document.getElementById('frmSignup');
// Set the token as the value for the token input
myForm.token.value = data.response.token.token;
// IMPORTANT: Here we call `submit()` on the form element directly instead of using jQuery to prevent and infinite token request loop.
myForm.submit();
};
// Called when token creation fails.
var errorCallback = function(data) {
// Retry the token request if ajax call fails
console.log("error::"+data.errorMsg);
if (data.errorCode === 200) {
// This error code indicates that the ajax call failed. We recommend that you retry the token request.
} else {
alert(data.errorMsg);
}
};
var tokenRequest = function() {
// Setup token request arguments
var args = {
sellerId: "<?php echo accountnumber_checkout; ?>",
publishableKey: "<?php echo publickey_checkout; ?>",
ccNo: $("#creditcardno").val(), //input field
cvv: $("#billingcvv").val(), //input field
expMonth: $("#expiryMonth").val(), //input field
expYear: $("#expiryYear").val() //input field
};
// Make the token request
TCO.requestToken(successCallback, errorCallback, args);
};
$(function() {
// Pull in the public encryption key for our environment
TCO.loadPubKey('sandbox');
$("#frmSignup").submit(function(e) {
// Call our token request function
tokenRequest();
// Prevent form from submitting
return false;
});
});
</script>
</form>
Facing this error: ( in 2co.min.js 2:1628 )
Uncaught ReferenceError: tokenRequestUrl is not defined
If I use 'production' in TCO.loadPubKey('production') instead of 'sandbox', then the token is generated. But, in production mode, I am not able to use test cards:
Test Payment Methods
Related
I am using Google recaptcha v3 in my site by following official guideline.
but when i opened Browser Console and write the following code
function flood(){
var chars = 'abcdefghijklmnopqrstuvwxyz1234567890';
var string = '';
for(var ii=0; ii<15; ii++){
string += chars[Math.floor(Math.random() * chars.length)];
}
email = document.getElementById("email");
email.value = string+"#gmail.com";
$("#submitBtn").trigger("click");
}
setInterval(flood, 1000);
Here you can see in image preview about 37 spam requests sent to server successfully.
Image
Anyway to avoid this?
Thanks
Follwoing JavaScript code i use in frontend.
$('#newsletterForm').submit(function(event) {
$("#submitBtn").attr("disabled", true);
$("#ajax-response").fadeIn();
event.preventDefault();
var email = $('#email').val();
grecaptcha.ready(function() {
grecaptcha.execute('6LfX1N4bAAAAABRp1LK3Io5u8pq7xn9iYqiXioru', {action: 'process'}).then(function(token) {
$('#newsletterForm').prepend('<input type="hidden" id="token" name="token" value="' + token + '">');
$('#newsletterForm').prepend('<input type="hidden" id="action" name="action" value="process">');
//$('#newsletterForm').unbind('submit').submit();
$.post("./process.php", {
email: $("#email").val(),
token: $("#token").val(),
action: $("#action").val()
}, function (response) {
console.log(response);
$("#message").text(response);
$("#submitBtn").attr("disabled", false)
$("#ajax-response").fadeIn();
})
});;
});
});
and backend in php
// other code...
// use the reCAPTCHA PHP client library for validation
$recaptcha = new \ReCaptcha\ReCaptcha(RECAPTCHA_V3_SECRET_KEY);
$resp = $recaptcha->setExpectedAction($action)
->setScoreThreshold(0.5)
->verify($token, $_SERVER['REMOTE_ADDR']);
if ($resp->isSuccess()) { // success process }
else {// spam request}
I guess you misunderstood the concept... You can never prevent people to send requests to your server with javascript code... You have to always check on the server side too... That's why you are using reCaptcha like solutions. This makes sure that the request comes from your original site / frontend using reCaptcha with a valid token... If it's not valid you won't be doing any "source expensive" operations on the serverside.
I have an error in my XMLHttpRequest() when sending a post request to my url. When I check my console.log it says
this line of code:
xhr.send();
Error: Failed to load resource: the server responded with a status of 419 (unknown status)
Here's my script code using only pure javascript:
<!-- Get Parameters for gclid or token when user visits the website -->
<script>
window.onload = function() {
try {
var url_string = (window.location.href).toLowerCase();
var url = new URL(url_string);
// Get Gclid
var token = url.searchParams.get("gclid");
// gclid expires in 6 hours
document.cookie = `gclid=${gclid}; max-age=21600`;
// Sending a get request to laravel controller
var base_url = window.location.origin; // get the base url
var params = "gclid=" + gclid;
let xhr = new XMLHttpRequest();
xhr.open("POST", base_url+"/storetrackvisit?"+params, true);
xhr.send();
} catch (err) {
console.log("Issues with Parsing URL Parameter's - " + err);
}
}
</script>
I'm trying to pass parameters in this XMLHttpRequest() so that when users has this parameters.
Example:
https://www.test.com/?gclid=312
It will send a post request to my storetrackvisit page along with the parameters and save it to db:
https://www.test.com/storetrackvisit?gclid=312
let xhr = new XMLHttpRequest();
xhr.open("POST", base_url+"/storetrackvisit?"+params, true);
xhr.send();
so that it will save to my controller like this:
TrafficController
public function storeParams(Request $request)
{
$traffic = new TrafficTracking();
if ($request->has('gclid')) { // check if key = gclid
$traffic->traffic_type = 'gclid'; // store the key in db
$traffic->traffic_value = $request->gclid;
}
if ($traffic->value === null) {
return response()->noContent();
}
$traffic->ip_address = $request->ip();
$traffic->domain = $request->getHttpHost();
$traffic->save();
}
web.php
// Traffic Controller
Route::post('/storetrackvisit', 'TrafficController#storeParams')->name('user.store.trackvisit');
What seems to be an error in my xhr.send(); returning a status of 419 (unknown status)?
Is it because there is no csrf token passed along with my XMLHttpRequest in javascript? If so, how do I pass it in the XMLHttpRequest or maybe what's causing the 419 (unkown status)?
Usually a 419 Error means a missing CSRF token from a request. You can handle it easily in two ways.
Change the route to GET if you're not sending any sensitive info.
Include a CSRF token in your request.
I will explain about point number 2, how can you include a CSRF token in your request.
Now, there are also two ways to include a CSRF token:
Call it in header.
Create a HTML input field containing token.
1. Call it in Headers
You can define CSRF token in your header like this,
<meta name="csrf-token" content="{{ csrf_token() }}">
and then access it in JavaScript and set headers for it like this,
xhr.setRequestHeader(header, value);
2. Create a HTML input field containing token
You can create an input field containg token like this,
<!-- It's a laravel blade directive, which creates an input field containing token -->
#csrf
<!-- or manually do it -->
<input type="hidden" name="_token" value="{{ csrf_token() }}">
Get it in your JavaScript and send it as a parameter like this,
let csrfToken = document.getElementsByName("_token");
params += "&_token=" + csrfToken;
suppose I work with some kind of API and my file server.php handles the connection to the API service. on my client side I use AJAX call like this:
$http({
url : 'server/server.php',
method : 'GET',
data : { getContent : true }
});
in my server.php I handle it like this:
if(isset($_GET['getContent'])){
$content = get_content();
}
function get_content(){...}
i just wonder what prevents any one send AJAX call with the same getContent parameter and get all my data? how can i secure it and make sure only calls from my application will get the relevant data back?
thank you!
I guess you are concerned about CSRF attacks. Read more about this here: https://www.owasp.org/index.php/Cross-Site_Request_Forgery_%28CSRF%29_Prevention_Cheat_Sheet
One of the mostly used option to secure your request will be:
- Generate a token and send it with the request for a session. This token can be identified by your WebServer as originating from a specific client for a specific session
2022 Update
This is a 7 year old post and the link in the link-only "accepted" answer is broken.
So, I'm going to offer a basic walkthrough and a complete model.
Remember, the $_SESSION will be preserved even in the AJAX handler, if it's all from the same domain. So, you can use that to check things.
Use $_POST
I presume you're using $_POST and not $_GET since you're concerned about security. If not, then much of this might not be important anyway.
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
$post_method = true;
}
Ensure the $_SERVER['HTTP_REFERER'] is from your own site
if ( (!empty($_SERVER['HTTP_REFERER']))
&& ($_SERVER['HTTP_REFERER'] === "https://example.tld/my_sending_page.php") ) {
$from_my_server = true;
}
If you're not sure what this should be, run a test on your own server to see what this should be:
echo $_SERVER['HTTP_REFERER'];
Verify XMLHTTP/AJAX request via $_SERVER array
if ( (!empty($_SERVER['HTTP_X_REQUESTED_WITH']))
&& ( strtolower($_SERVER['HTTP_X_REQUESTED_WITH']) === 'xmlhttprequest') ) {
$ajax = true;
} else {
$ajax = false;
}
Use a token
This is the hard part, but not too hard.
Create the token
Set the token in $_SESSION
Put the token in the AJAX header
AJAX responder: confirm the AJAX header token with the $_SESSION token
send_from_me.php
// Create the token
//$token = md5(rand(10000,99999)); // Not recommended, but possible
$token = bin2hex(random_bytes(64));
// Store in SESSION
$_SESSION["token"] = $token;
// Assuming your AJAX is this
const AJAX = new XMLHttpRequest();
// This goes inside your AJAX function somewhere before AJAX.send
//
AJAX.setRequestHeader("ajax-token", "<?php echo $_SESSION["token"]; ?>");
//
// That creates $_SERVER['HTTP_AJAX_TOKEN'] which we can use later
ajax_responder.php
session_start(); // Must have
if ($_SERVER['HTTP_AJAX_TOKEN'] === $_SESSION["token"]) {
$token_match = true;
} else {
echo "No script kiddies!";
exit();
}
// Now it's safe for your AJAX responder to proceed
Let's put all of this into a working example
sending_from.php
<?php
session_start();
$token = bin2hex(random_bytes(64));
$_SESSION["token"] = $token;
?>
<!DOCTYPE html>
<html>
<head>
<title>My AJAX Sender</title>
</head>
<body>
<script>
function ajaxFormData(formID, postTo, ajaxUpdate) {
// Bind a new event listener every time the <form> is changed:
const FORM = document.getElementById(formID); // <form> by ID
const FD = new FormData(FORM); // Bind to-send data to form element
const AJAX = new XMLHttpRequest(); // AJAX handler
// This runs when AJAX responds
AJAX.addEventListener( "load", function(event) {
document.getElementById(ajaxUpdate).innerHTML = event.target.responseText;
} );
// This runs if AJAX fails
AJAX.addEventListener( "error", function(event) {
document.getElementById(ajaxUpdate).innerHTML = 'Oops! Something went wrong.';
} );
// Add your token header
AJAX.setRequestHeader("ajax-token", "<?php echo $_SESSION["token"]; ?>");
// Open the POST connection
AJAX.open("POST", postTo);
// Data sent is from the form
AJAX.send(FD);
}
</script>
<div id="ajax_changes">Replace me with AJAX</div>
<form id="ajaxForm">
<input type="text" name="the_simple_response">
<button type="button" onclick="ajaxFormData('ajaxForm', 'ajax_responder.php', 'ajax_changes');">Send my Secure AJAX</button>
</form>
</body>
</html>
ajaxcheck.inc.php
<?php
$mysite = 'https://example.tld';
// All in one test
if (($_SERVER['REQUEST_METHOD'] == 'POST')
&& ((!empty($_SERVER['HTTP_REFERER'])) && ($_SERVER['HTTP_REFERER'] === "$mysite/my_sending_page.php"))
&& ((!empty($_SERVER['HTTP_X_REQUESTED_WITH'])) && ( strtolower($_SERVER['HTTP_X_REQUESTED_WITH']) === 'xmlhttprequest'))
&& ($_SERVER['HTTP_AJAX_TOKEN'] === $_SESSION["token"])) {
$ajax_legit = true;
} else {
echo "No script kiddies!";
exit();
}
?>
ajax_responder.php
<?php
session_start();
// Do all that checking we're learning about by neatly including the file above
require_once('ajaxcheck.inc.php');
// Process your AJAX
echo $_POST['the_simple_response'];
?>
i just wonder what prevents any one send AJAX call with the same getContent parameter and get all my data?
Nothing. This URL is public thus anyone can make requests to it.
how can i secure it and make sure only calls from my application will get the relevant data back?
You can pass additional data (for example, some hashed value) that is verified on the server side.
$http({
url : 'server/server.php',
method : 'GET',
data : { getContent : true, hash : '0800fc577294c34e0b28ad2839435945' }
});
and
if(isset($_GET['getContent']))
{
if(isset($_GET['hash']) && validateHash($_GET['hash']))
{
$content = get_content();
}
}
function get_content(){...}
i just wonder what prevents any one send AJAX call with the same getContent parameter and get all my data?
The same way you would protect the data in any other request (e.g. with user authentication). There's nothing special about Ajax in regards to HTTP as far as the server is concerned.
how can i secure it and make sure only calls from my application will get the relevant data back?
You can't. The user can always inspect what their browser is asking the server for and replicate it.
Generally, people authenticate users rather than applications.
I'm using the code example from Stripe's documentation located here. But, when this is processed $form.get(0).submit(); I'm getting this error.
Uncaught TypeError: Property 'submit' of object #<HTMLFormElement>
is not a function
My code is below:
var stripeResponseHandler = function(status, response) {
var $form = $('#payment-form');
if (response.error) {
// Show the errors on the form
$form.find('.payment-errors').text(response.error.message);
$form.find('button').prop('disabled', false);
} else {
// token contains id, last4, and card type
var token = response.id;
console.log(token);
// Insert the token into the form so it gets submitted to the server
$form.append($('<input type="hidden" name="stripeToken" />').val(token));
// and re-submit
$form.get(0).submit(); **//Error happens here**
}
};
jQuery(function($) {
$('#payment-form').submit(function(e) {
var $form = $(this);
// Disable the submit button to prevent repeated clicks
$form.find('#payment-button').prop('disabled', true);
Stripe.createToken($form, stripeResponseHandler);
// Prevent the form from submitting with the default action
return false;
});
});
What am I doing wrong?
On the line you're getting the error, try this instead:
jQuery($form.get(0)).submit();
Your problem is that you're getting the first HTML element, but in order to call "submit" on that, you need to wrap it with jQuery.
I have a form that I use for login purposes here:
<form id = "membershipInfo" method = "post" action = "Login.aspx">
with an submit button that I want to do a post method and a javascript onclick method like this:
<input type ="submit" id = "submitInfo" class = "MemberInfo" value = "Take Me There!" onclick = "authorize(accept, reject)"/>
The method in the onclick is an facebook authorize method that will pull information from the user (access token). I need this token to have the user proceed in my program. The issue is that when this button is clicked the post method will happen before the onclick is finished, which means that the access token will never be passed with the form.
To get the access token to the page load method I use a hidden input in the form:
<input type = "hidden" id = "hiddenAccessToken" name = "accessToken" value = "<%=accessToken %>" />
and in the Facebook method I get the access token like this:
function authorize(successCallback, failureCallback) {
FB.getLoginStatus(function (response) {
if (response.session) {
// logged in and connected user, carry on
session = response.session;
//Set access token
accessToken = response.session.access_token;
//Call success callback
successCallback();
} else {
// no user session available, Lets ask for perms
FB.ui(
{
method: 'permissions.request',
perms: permissionString
},
function (response) {
if (response && response.session != null) {
//Get session
session = response.session;
//Set access token
accessToken = response.session.access_token;
//Call success callback
successCallback();
} else {
//Call failure callback
failureCallback();
}
});
}
});
//Method hit on successCallback
function accept() {
//Add access token to hidden input
$('#hiddenAccessToken').val(accessToken);
}
I don't want to use a time out (and I don't think that will work anyways), but I need to slow the page load down until these js methods are complete. Any suggestions?
Why don't you do the form submit with js, like this:
<input type ="button" id = "submitInfo" class = "MemberInfo" value = "Take Me There!" onclick = "authorize(accept, reject)"/>
And then:
function accept() {
//Add access token to hidden input
$('#hiddenAccessToken').val(accessToken);
$('#membershipInfo').submit();
}