Wordpress wp_signon() do not work in ajax call - javascript

I am trying to build an costum login to Wordpress in a AJAX call. I a remove the wp_signon() from the PHP function I do get the right echo. But then I add the wp_signon() it always return my whole login page in HTML. I can't see what I am doing wrong. And can't get the login to work.
Please help!
js
$.ajax({
method: 'POST',
url: '/wp-admin/admin-ajax.php',
dataType: 'json',
data: {
'action': 'getLoggedIn',
'user_name': user_name,
'user_password': user_password,
'user_remember': user_remember
},
success: function(response) {
if (response === 'ok') {
window.location = '/app/';
}
},
error: function(){}
});
PHP
function getLoggedIn() {
global $wpdb;
// Check if users is already logged in
if ( is_user_logged_in() ) {
echo 'You are already logged in';
die;
}
//We shall SQL escape all inputs
$username = $wpdb->escape($_REQUEST['user_name']);
$password = $wpdb->escape($_REQUEST['user_password']);
$remember = $wpdb->escape($_REQUEST['user_remember']);
$creds = array();
$creds['user_login'] = $username;
$creds['user_password'] = $password;
$creds['remember'] = $remember;
$user_signon = wp_signon( $creds, false );
// Check if error
if ( is_wp_error($user_signon)) {
echo $user_verify->get_error_code();
exit();
} else {
echo 'ok';
exit;
}
die();
}
add_action('wp_ajax_getLoggedIn', 'getLoggedIn');
add_action('wp_ajax_nopriv_getLoggedIn', 'getLoggedIn');

The problem was not the wp_signon() function. It was an other Wordpress action that redirects the page after user login has failed. This:
add_action( 'wp_login_failed', 'login_failed' );

I got caught up in the same situation. did you remove that wp_login_failed action or how did you work this out?

Related

Handling ajax response exceptions

I am currently handling a form with php and calling it via an ajax request, i want to handle exceptions showing a small div instead of the basic popup
so i did multiple if conditions based on the responsetext, however one of the exceptions doesnt get handled
This exception is the empty fields exception it always shows the wrong username or pw instead
here is the ajax call
function sendLogin(){
username = $('#loginEmail').val();
password = $('#loginPassword').val();
a = $.ajax({
type: 'post',
data: 'username='+username+'&password='+password,
url: '/account/login.php',
async: false,
});
if(a.responseText == "LoggedIn"){
$("#WrongPW_Error").fadeOut("fast");
$("#Empty_Error").fadeOut("fast");
$("#LoggedIn").fadeIn("fast");
setTimeout(location.reload(),2200);
}
else if(a.responseText == "Empty_Fields") {
//alert(a.responseText);
$("#WrongPW_Error").fadeOut("fast");
$("#Empty_Error").fadeIn("fast");
}
else if(a.responseText == "Wrong_Credentials") {
//alert(a.responseText);
$("#Empty_Error").fadeOut("fast");
$("#WrongPW_Error").fadeIn("fast");
}
}
and here is the php file
<?php
if(!isset($_POST['username']) || !isset($_POST['password'])){
echo "Empty_Fields";
die();
}
$username = $_POST['username'];
$password = $_POST['password'];
$hashed_pass = hash("sha512", $password);
$stmt = $dbh->prepare("SELECT Count(email)as total, username from Users where email = :username and password= :password");
$stmt->bindParam(':username', $username, PDO::PARAM_STR);
$stmt->bindParam(':password', $hashed_pass, PDO::PARAM_STR);
$stmt->execute();
$row = $stmt->fetch(PDO::FETCH_ASSOC);
$total = $row['total'];
if($total == 1){
session_start();
$_SESSION['user'] = $username;
$_SESSION['user_name'] = $row['username'];
echo "LoggedIn";
die();
}
else{
echo "Wrong_Credentials";
die();
}
?>
You are not performing the correct check in PHP to see if the POST variables are empty.
Read: What's the difference between 'isset()' and '!empty()' in PHP?
isset($_POST['username'])
will return true if the POST parameter exists, even if its content is an empty string. You need both tests: isset AND empty.
if(!isset($_POST['username']) || !isset($_POST['password'])){
echo "Missing_Param";
die();
}
if(empty($_POST['username']) || empty($_POST['password'])){
echo "Empty_Fields";
die();
}
Edit: I did not notice that you're using async: false; leaving this answer for reference. In general it's a good idea to use non-blocking calls in JS so other UI elements aren't affected.
$.ajax does not return anything; it's an asynchronous call that will call a function when it completes. You'll need to do something like this:
$.ajax({
// other arguments here
success: function(data) {
// handle success
},
error: function() {
// handle error
}
});
More examples available here and here.
Instead of calling die() on your PHP code, send an error response. Call http_response_code(401) (not authorized response). Second issue is that $.ajax doesn't return a response and async = false has been deprecated and should not be used. Instead, define two functions for success and failure and just set those as the success and error parameters of your AJAX request.
$.ajax({
type: 'post',
data: 'username='+username+'&password='+password,
url: '/account/login.php',
async: false,
success: successFunction,
error: errorFunction
});
function successFunction(response){
$("#WrongPW_Error").fadeOut("fast");
$("#Empty_Error").fadeOut("fast");
$("#LoggedIn").fadeIn("fast");
setTimeout(location.reload(),2200);
}
function errorFunction(response){
$("#WrongPW_Error").fadeOut("fast");
$("#Empty_Error").fadeIn("fast");
}

How to protect jquery button with Invisible reCaptcha?

I want to protect my jquery button from bots without annoying the users, so i thought of adding google's invisible recaptcha to it. However implementation isn't as easy as i though and i can't seem to do it. If anyone can show me how it's done it would be great. PS: I am doing this on a wordpress theme.
This is the documentation:
https://developers.google.com/recaptcha/docs/invisible
Create invisible recaptcha:
https://www.google.com/recaptcha/admin#beta
And this is what i have:
HTML:
<button class="acf-get-content-button">Show Link</button>
<div class="fa" id="acf-content-wrapper" data-id="<?php echo $post_id; ?>"></div>
JS:
<script>
(function($) {
$('.acf-get-content-button').click(function(e) {
e.preventDefault();
$('.fa').addClass('fa-cog fa-spin fa-4x');
var $contentWrapper = $('#acf-content-wrapper');
var postId = $contentWrapper.data('id');
$.ajax({
url: "/public/ajax.php",
type: "POST",
data: {
'post_id': postId
},
})
.done(function(data) {
$('.fa').removeClass('fa-cog fa-spin fa-4x');
$contentWrapper.append(data);
$('.acf-get-content-button').removeClass().addClass('.acf-get-content-button')
});
});
$('.acf-get-content-button').mouseup(function() {
if (event.which == 1) {
$(".acf-get-content-button").hide();
}
});
})(jQuery);
</script>
ajax.php
<?php
define('WP_USE_THEMES', false);
require_once( $_SERVER['DOCUMENT_ROOT'] . '/wp-load.php' );
global $post;
$post_id = $_REQUEST["post_id"];
$content = get_field( 'ebook_link_pdf', $post_id );
echo ($content);
You can use Invisible reCaptcha for WordPress plugin to do it easily if you think coding from scratch is complicated for you. You can also dig into the source code of the plugin to get an idea about the implementation.
This plugin has actions and filters for custom use and these are documented on plugin homepage.
I went ahead to experiment with reCaptcha.
Turns out according to the API, you could use the grecaptcha.getResponse method to submit to your AJAX call. (But Note that this reCaptcha API is still in beta and could change...) Here is a short example:
HTML:
<div id="test-captcha" class="g-recaptcha" data-sitekey=[Your site key]></div>
<button id="load" onclick="go();">Load something</button>
Javascript:
function go()
{
$.ajax({
url: "/captchatest.php",
type: "POST",
data: {
'g-recaptcha-response': grecaptcha.getResponse()
}
}).done(function(data) {
alert(data);
});
}
captchatest.php
<?php
//Used http://stackoverflow.com/a/6609181/7344257
function do_post_request($url, $data)
{
// use key 'http' even if you send the request to https://...
$options = array(
'http' => array(
'header' => "Content-type: application/x-www-form-urlencoded\r\n",
'method' => 'POST',
'content' => http_build_query($data)
)
);
$context = stream_context_create($options);
$result = file_get_contents($url, false, $context);
if ($result === FALSE) { /* Handle error */ }
return $result;
}
$error = "";
if ($_SERVER["REQUEST_METHOD"] === "POST")
{
if (!isset($_POST['g-recaptcha-response']))
{
echo "Please do reCaptcha";
exit(0);
}
$data = array("secret" => "6LeUGhYUAAAAABNS5OtOc9vonTlyrtgcQ5VdI7cV",
"response" => $_POST['g-recaptcha-response'],
"remoteip" => $_SERVER["REMOTE_ADDR"] //This is optional.
);
$resp = json_decode(do_post_request("https://www.google.com/recaptcha/api/siteverify", $data));
if (!$resp->success)
{
//use $resp->error-codes to debug error.
echo "Invalid reCaptcha";
exit(0);
}
echo "Received secret code.";
exit(0);
}
?>
I wasn't sure if you could use cURL. So I decided to just stick with the basic PHP code. You would also have to format the errors, but I think you should get the point.

Ajax call using php file placed in theme folder in Osclass classified script?

I am using Osclass classified script, trying to alert a message returned by ajax call.
My ajax-test.php file which is saved in my theme folder contains
<?php
$name = $_GET["name"];
echo "I am " . $name
?>
and my JavaScript function code is
function findName() {
var name = "Jhon";
$.ajax({
method: "POST",
// url: "oc-content/themes/bender/ajax-test.php",
url: 'http://127.0.0.1/osclass/index.php?page=ajax&action=custom&ajaxfile=ajax-test.php',
data: { name : name },
success: function (data) {
alert(data);
},
})
}
Anybody tell me what am I doing wrong? it alerts
{"error" => "ajaxFile doesn't exist"}
Note: It works fine with commented line of code
You are using
> method: "POST",
in ajax then why are you using GET ?
$name = $_GET["name"];
Using Post to getting value for it.
$name = $_POST["name"];
Unfortunatelyn, that's not exactly how the ajax.php custom action works.
First, page=ajax&action=custom doesn't work with themes, only with plugins since it will search ajaxfile inside the plugins folder by doing something like this:
$filePath = osc_plugins_path() . $ajaxfile; // eg. /oc-content/plugins/$ajaxfile
You then have to pass in ajaxfile the name of the plugin to work. If you were using the Madhouse Messenger plugin, you would do something like:
page=ajax&action=custom&ajaxfile=madhouse_messenger/main.php
However, since 3.3, when using page=ajax&action=custom, you do not use the ajaxfile param anymore but the route param. You can take a look at how routes work here and some examples of routes here.
in your theme functions.php
add something like this:
//name of your custom ajax request
$my_custom_ajax_request_name = 'doSomethingCool';
osc_add_hook('ajax_' . $my_custom_ajax_request_name, $my_custom_ajax_request_name);
function doSomethingCool()
{
// set default response
$response = [
'status' => false,
'msg' => 'Default Error Message...',
];
// token protection
// read more about csrf token:
// https://dev.osclass.org/2013/02/19/make-your-plugins-more-secure-with-anti-csrf-functions/
osc_csrf_check();
// get request parameters
$param1 = Params::getParam('param1');
$param2 = Params::getParam('param2');
// do some logic here ex: check if user is logged in
if (osc_is_web_user_logged_in()) {
$response['status'] = true;
$response['msg'] = 'User is logged in. ;-) ' . $param1 . ' ' . $param2 . '! ' . osc_logged_user_name();
} else {
$response['status'] = false;
$response['msg'] = 'User is not logged in. :-(';
}
// return json response
header('Content-Type: application/json');
echo json_encode($response);
exit;
}
some where in your template files like header.php, footer.php or everything else you need it...
<a data-param1="hello" data-param2="world" href="#" id="make-an-ajax-request">
Make an AJAX Request!
</a>
<script>
//here we hold some usefull info for easy access
var mySite = window.mySite || {};
mySite.base_url = '<?php echo osc_base_url(true); ?>';
mySite.csrf_token = '<?php echo osc_csrf_token_url(); ?>';
$(function(){
$('#make-an-ajax-request').on('click', function(e){
e.preventDefault();
// name of our custom ajax hook
var ajax_hook = 'doSomethingCool';
// get parameters
var param1 = $(this).data('param1');
var param2 = $(this).data('param2');
// build axjxa url
var url = mySite.base_url + '?page=ajax&action=runhook&hook='+ajax_hook+'&'+mySite.csrf_token;
//build data
var data = {
param1 : param1,
param2 : param2
};
$.ajax({
type: 'POST',
dataType: 'json',
data: data,
url: url
}).done(function (data) {
console.log(data);
if (data.status) {
} else {
}
});
});
});
</script>
OSCLASS WAY
to note that the current osclass way of doing an ajax request from a theme page is to call the
http://example.com/?page=ajax&action=runhook&hook=MY_HOOK_FUNCTION_NAME
and register it like osc_add_hook('ajax_MY_HOOK_FUNCTION_NAME',
'MY_HOOK_FUNCTION_NAME'); optionally but very recommended is the use
of the csrf token that you can implement like i have done for url or
by calling the osc_csrf_token_form() directly into your form.
NON OSCLASS WAY
just create a file in your theme or everywhere you want and make sure to put this into it <?php require_once __DIR__ . RELATIVE_PATH_TO_OC_LOAD_FILE . 'oc-load.php'; ?> then build your logic into it.

PHP file which is opened by AJAX - Give Captcha alert and send url-data

Sitting on this already the whole day, if you believe or not :)
I want to transfer data via GET-Method to an external .jsp file (example.com/data.php?attribute=value&a2=v2 and so on)
This all seems to work so far and also the validation. Now I have the problem that I have a captcha which is generated by a php-file and the captcha is controlled/validated in the PHP-File where the HTML-Form data is posted to.
When everything is OK I can do a alert in the submitHandler (success: function(response)) but how can I get an alert now, if the Captcha is incorrect?
How can I solve this? Can I get a value oder variable throught AJAX back from the PHP File to do something with it (to display the alert)?
Would be very glad for any help or comments.
Thank you!
HERE the data is validated and sent to PHP file after successful validation.
<script src="http://ajax.aspnetcdn.com/ajax/jquery.validate/1.9/jquery.validate.min.js"></script>
<script type="text/javascript">
(function($,W,D)
{
var JQUERY4U = {};
JQUERY4U.UTIL =
{
setupFormValidation: function()
{
$("#form-id").validate({
rules: {
firstname: "required",
.........
},
messages: {
firstname: "Please enter your firstname",
..........
},
submitHandler: function(form)
var data = $("#nachricht").serializeArray();
$.ajax({
type:"POST",
url:"nachricht.php",
data: data,
dataType: "text",
success: function(response) {
alert('Thank you!');
}
});
}
});
}
}
$(D).ready(function($) {
JQUERY4U.UTIL.setupFormValidation();
});
})(jQuery, window, document);
THE PHP FILE:
Here the data is transferred to another URL (GET-Method) and the Captcha is checked
$email = urlencode($_POST['email']);
$name = urlencode($_POST["name"]);
....
session_start();
if(isset($_SESSION['captcha_spam']) AND $_POST["captchafield"] == $_SESSION['captcha_spam']) // Captcha korrekt
{
unset($_SESSION['captcha_spam']);
$link = "http://www.example.com/data.jsp?email=" . $email . "&name=" . $name . $titel . "&text=" . $text . "&ranking=" . $ranking . "&captchafield=" . $captcha_s;
header( "refresh:0;url=" . $link);
exit;
....
OK so now I have in my PHP file where the form is submitted to:
if(enteredcaptcha == captcha){
echo "<script type='text/javascript'> alert('captcha_correct');</script>";
} else {
echo "<script type='text/javascript'> alert('captcha_not_correct');</script>";
}
and in my normal HTML file where the Form and Javascript is I have:
submitHandler: function(form) {
var data = $("#kommentar").serializeArray();
$.ajax({
type:"POST",
url:"kommentar.php",
data: data,
dataType: "text",
success: function(response) {
if( response == "captcha_is_correct" ){ alert("Success"); } else { alert("unsuccess.."); }
}
});
}
And this makes really sense, wonderful, but I'm always getting the message "unsucces", so I think there is still a bug somehow?

Redirect in PHP on AJAX call

I need to redirect to another page in my PHP code on an AJAX call. The only thing I can seem to find online about this is to do it through JavaScript using window.location.href = 'url'; but it does not work.
If I try to redirect using the window.location.href to profile.php?user=person then it has the url localhost/profile.php?user=person but if I type in the full URL for the redirect like project/login/profile.php?user=person then it stays on the same page. The profile.php page only echo's what who the user in the url is.
Any ideas?
Here is my code:
$.ajax({
url: 'processes/login.inc.php',
type: 'post',
data: data,
success: function(res) {
if(res != '4502') {
var s = 'profile.php?user='+res;
window.location.href = s;
}
}
});
and the PHP:
<?php
require_once('../core/init.php');
$username = escape($_POST['ul']);
$password = escape($_POST['pl']);
$user = new User();
$login = $user->login($username, $password);
if($login) {
// Redirect::to('../profile.php?user='.$username);
echo $username;
} else {
echo '4502';
}
You have to assign the full path, not only the php file and parameters, for example:
Change:
location.href = 'profile.php?user=person';
To:
location.href = '/login/profile.php?user=person';

Categories