I have a settings form that I want to ensure the user doesnt make changes by mistake. When the user is done they will click the save button which will pop up a modal (Bootstrap modals) prompting the user to enter their password to continue with processing the original form.
If the password entered is correct then the first form is submitted, else the page is reloaded / redirected back to itself. The first form will include many fields, but i am just using the one for testing.
<form action="http://localhost.testing/render_confirm_with_password.php" method="POST" id="validation-form" class="form-horizontal confirm-form">
<div class="form-group">
<label for="deletion_reason" class="col-xs-3 col-lg-4 control-label">Enter Your Value</label>
<div class="col-sm-9 col-lg-6 controls">
<input type="text" name="value" placeholder="yourname#email.com" class="form-control" />
</div>
</div>
<div class="form-group">
<div class="col-sm-9 col-sm-offset-3 col-lg-6 col-lg-offset-4">
<!-- <button type="submit" class="btn btn-primary"><i class="icon-ok"></i> Process</button> -->
<button type="submit" class="btn btn-primary" data-toggle="modal" data-target="#password_confirm_modal" data-modal-type="password_confirm" data-modal-title="Delete Transaction" data-modal-text="Are you sure you want to delete this transaction?"><i class="icon-ok"></i> Process</button>
</div>
</div>
</form>
When the user clicks save it will pop up the modal with the form inside is as shown below. This form is processed using jQuery $.ajax()
<form action="#" method="POST" id="validation-form" class="form-horizontal">
<div class="modal-body">
<div class="form-group">
<label for="deletion_reason" class="col-xs-3 col-lg-4 control-label">Password</label>
<div class="col-sm-9 col-lg-6 controls">
<input type="text" name="password" id="password" placeholder="your password" class="form-control" />
</div>
</div>
<p>PASSWORD RESULT -> <span id="password_result"></span></p>
</div>
<div class="modal-footer">
<button class="btn" data-dismiss="modal" aria-hidden="true">Close</button>
<button id="password_confirm_submit" class="btn btn-primary">Process</button>
</div>
</form>
The ajax code is shown below. Once the modals process button is clicked it sets the password before posting it through to the php page to be processed. In the php I check if the password matches the stored password and echo back MATCH or NO MATCH which gets shown in the modal. If the ajax result equals MATCH I then process the first form with $('.confirm-form').submit(); Im sure I haven't done this in a secure manner.
$('#password_confirm_submit').click(function(e){
var password = $('#password').val();
e.preventDefault();
$.ajax({
type: 'POST',
data: {password: password},
url: 'http://localhost.testing/process_confirm_with_password.php',
success: function(result){
$('#password_result').html(result);
if(result == "MATCH"){
// process form_1
$('.confirm-form').submit();
}else{
// back to form_1
}
}
})
});
I tried redirecting from within the PHP if the passwords didnt match but it still processed form one.
Don't worry, its hard coded just for testing
$password = "password";
if(isset($_POST['password'])){
$pw = $_POST['password'];
if($password == $pw){
// process form_1
echo "MATCH";
}else{
// return to form_1
header('Location: http://localhost.testing/confirm_with_password.html');
echo "NO MATCH";
}
}else{
// return to form_1
echo "NOT SET";
}
What the header function in your PHP code that handles the AJAX request does, is it redirects only the AJAX request and not the page in your browser. Remove the redirect as it will not return to form 1.
If you want to close the bootstrap modal box when the password was entered incorrectly, you'd call $("#password_confirm_modal").modal("hide"); or location.reload(); to refresh/reload the page from within your AJAX callback in your else statement where you handle the incorrect password response, but using the latter you would lose all the data entered into the form.
Instead of doing either of the two you could display a warning in the modal box about the password having been entered incorrectly, and let the user try entering the password again. As for the security aspect, you might want to add the correct password as a hidden field into your original form just before it is submitted, so that when saving the actual data the password can be verified.
Related
I am building a web application using the ASP.NET Core 3.1 MVC and Razor pages.
I am new to Razor pages.
I created a basic application using above. I created a registeration form having following three fields -
User name
User email address
Verification code
There are two buttons -
Send Code
Register
I am providing a feature in which the user can verify its email address before clicking on the "Register" button.
A verification code will be sent to the user to the email address, when user clicks on the "Send Code" button.
The user should then enter the code in the "Verification code" field and submit the form by clicking on the "Register" button.
Issue
When user clicks on the "Send Code" button, the code is send but the form data gets cleared i.e. "User name" and "User email address" fields values get erased. I used Ajax to call the "Send verification code" function. Following is the code -
Index.cshtml
<form class="form-horizontal" method="post">
<div class="form-row">
<label class="col-sm-2 control-label">Credentials</label>
</div>
<div class="form-group row">
<label asp-for="user.UserName" class="col-sm-2 col-form-label"></label>
<div class="col-sm-10">
<input type="text" asp-for="user.UserName" class="form-control" id="UserName"
name="UserName" placeholder="Enter Full Name"
value="">
</div>
</div>
<div class="form-group row">
<label asp-for="user.UserEmailAddress" class="col-sm-2 col-form-label"></label>
<div class="col-sm-10">
<input type="text" asp-for="user.UserEmailAddress" class="form-control"
value=""
name="UserEmailAddress" placeholder="Enter Email Address" id="UserEmailAddress">
<div class="form-inline">
<button id="btn1"
class="btn btn-primary mb-sm-1">
#Model.EmailVerifCodeLabel
</button>
<div id="grid" class="col">
<input type="text" asp-for="user.EmailVerifCode"
class="form-control" id="Emailverifcode" placeholder="Enter code">
</button>
</div>
</div>
</div>
</div>
<div class="form-group row">
<div class="col-sm-10">
<button type="submit" class="btn btn-primary">Register</button>
</div>
</div>
</form>
#section Scripts {
<script type="text/javascript">
$("#btn1").click(function () {
var UserName = $("#UserName").val();
var UserEmailAddress = $("#UserEmailAddress").val();
alert(UserName);
alert(UserEmailAddress);
$.ajax({
url: "#Url.Page("/Register")?handler=SendEmailVerificationCode",
method: "GET",
data: { UserName: UserName, UserEmailAddress: UserEmailAddress }
})
});
</script>
}
Index.cshtml.cs
public JsonResult OnGetSendEmailVerificationCode(string UserName, string UserEmailAddress)
{
Random generator = new Random();
String verifCode = generator.Next(0, 999999).ToString("D6");
_configuration.GetSection("ConnectionStrings").GetSection("DefaultConnection").Value;
HttpContext.Session.SetString("verifCode", verifCode);
_myemailSender = new EmailSender();
var emailresult = _myemailSender.SendEmailAsync(UserName, UserEmailAddress, verifCode, _configuration);
return null;
}
Question: What is the reason for the razor pages form data getting erased even after using Ajax call?
When user clicks on the "Send Code" button, the code is send but the form data gets cleared i.e. "User name" and "User email address" fields values get erased.
<button id="btn1" class="btn btn-primary mb-sm-1"> Model.EmailVerifCodeLabel</button>
You do not specify the type attribute for above <button> tag within your <form>, it would work as a submit button, which cause form submit and user inputs cleared.
To fix it, you can try to explicitly specify type="button" for btn1 button.
<button id="btn1" type="button"
class="btn btn-primary mb-sm-1">
#Model.EmailVerifCodeLabel
</button>
Or call preventDefault() method to prevent it from submitting a form.
$("#btn1").click(function (evt) {
evt.preventDefault();
var UserName = $("#UserName").val();
//...
I'm trying to type invoice number as input type i.e. 123456789
After I click Print Record button, the value of invoice number disappears like this:
Aslo I have wrote
<div class="form-group row">
<label for="invoice_no" class="col-sm-2 col-form-label">Inovice Number</label>
<div class="col-sm-10">
<input type="text" class="form-control col-sm-4" name="InvNumber" id="InvNumber" value="{{request()->input('InvNumber')}}">
</div>
</div>
And the Print button looks like:
<div class="form-group row">
<div class="col-sm-12 dol-12" >
<button class="btn btn-secondary float-right" onclick="printDiv()">Print Record</button>
</div>
And printDiv() function is:
<script type="text/javascript" language="javascript">
function printDiv(divName) {
var printContents = document.getElementById('printableArea').innerHTML;
document.body.innerHTML = printContents;
window.print();
}
Clicking a submit button will submit the form it is in.
Presumably, your form's action is the current URL, so it reloads the page.
The new page doesn't have the data in the form fields that you had typed into the previous page.
If you don't want to submit the form, use the type attribute to change the <button> from its default of submit.
As per the documenation, if you don't specify type of button it assumes it as submit button that is why your form is being submitted by default.
Add type="button" in your button
<button type="button" class="btn btn-secondary float-right" onclick="printDiv()">Print Record</button>
submit: The button submits the form data to the server. This is the
default if the attribute is not specified for buttons associated with
a form, or if the attribute is an empty or invalid value.
https://developer.mozilla.org/en-US/docs/Web/HTML/Element/button
I am using ajax but it behaves different. I just want code that I should
in Model , VIEW,Controller.
This while contain two operation insertion and fetching the data from that db.
![In image their is subject and textarea as input.When i click submit the input
dispaly in comment which is just above the Subject input]1
View
<form action="" method="POST">
<input type="hidden" name="myId" id="myId" value="" />
<div class="form-group px-4">
<label for="subject">Subject</label>
<input type="text" id="js_subject" name="js_subject">
</div>
<div class="form-group px-4">
<label for="exampleFormControlTextarea1">Example textarea</label>
<textarea class="form-control" name = "js_text" id="js_text" rows="3"></textarea>
</div>
<input type="submit" id="comment-info" value="submit" name="submit" class="btn btn-primary">
</form>
Use an jQuery Ajax request,and on somepage.php use if and else for insert and select and
echo some message for both and die();
$('form').on('submit', function(event){
event.preventDefault();
$.ajax({
type:'post',
url:'somepage.php',
data:$(this).serialize(),
success:function(data){
var tmp = data;
if(data = "message1"){
//do whatever
}else if(data = "message2"){
//do whatever
}
})
});
In Laravel 5.6 I am using it's default authentication feature. However I have implemented a modal to replace the default login form. I am trying to keep a login modal form open and display errors upon failed login attempt. My login modal form looks like this:
<!-- Modal HTML Markup -->
<div id="login-modal" class="modal fade">
<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>
<h1 class="modal-title">Login</h1>
</div>
<div class="modal-body">
<div class="cs-login-form">
<form role="form" method="POST" action="{{ url('/login') }}">
<div class="input-holder">
{{ csrf_field() }}
<div class="form-group">
<label for="email" class="control-label">E-Mail Address</label>
<div>
<input id="email" type="email" class="form-control" name="email" value="{{ old('email') }}" autofocus>
</div>
</div>
</div>
<div class="input-holder">
<div class="form-group">
<label for="password" class="control-label">Password</label>
<div>
<input id="password" type="password" class="form-control" name="password">
</div>
</div>
</div>
<div class="form-group">
<div>
<div class="checkbox">
<label>
<input type="checkbox" name="remember"> Remember Me
</label>
</div>
</div>
</div>
<div class="form-group">
<div>
<button type="submit" class="btn btn-primary">
Login
</button>
<a class="btn btn-link" href="{{ url('/password/reset') }}">
Forgot Your Password?
</a>
</div>
</div>
</form>
</div>
</div>
</div><!-- /.modal-content -->
</div><!-- /.modal-dialog -->
</div>
Currently when a user enters invalid credentials the modal disappears and the user is redirected back to the home page with no errors. My login controller has not been altered and it looks like this
<?php
namespace App\Http\Controllers\Auth;
use App\Http\Controllers\Controller;
use Illuminate\Foundation\Auth\AuthenticatesUsers;
class LoginController extends Controller
{
/*
|--------------------------------------------------------------------------
| Login Controller
|--------------------------------------------------------------------------
|
| This controller handles authenticating users for the application and
| redirecting them to your home screen. The controller uses a trait
| to conveniently provide its functionality to your applications.
|
*/
use AuthenticatesUsers;
/**
* Where to redirect users after login.
*
* #var string
*/
protected $redirectTo = '/home';
/**
* Create a new controller instance.
*
* #return void
*/
public function __construct()
{
$this->middleware('guest')->except('logout');
}
}
you can submit your credentials using an ajax call, then inside your success method, you can check whether it's successful or not & show error if not ok. If it's ok, you can hide modal manually & redirect user to home page.
You would need to setup a function manually as Laravel's documentation explains. You will also need a route and an ajax request to make the login.
Custom Login route:
Route::post('/login', 'LoginController#authenticate');
In your view you will first need to setup a meta tag with the csrf token to protect yourself from attacks:
<meta name="csrf-token" content="{{ csrf_token() }}">
Then in your ajax you could do this:
$.ajax({
headers: {
'X-CSRF-TOKEN': $('meta[name="csrf-token"]').attr('content')
},
type: 'POST',
url: '/login',
data: [email: '', password: ''],
success: function(controllerResponse) {
if (!controllerResponse) {
// here show a hidden field inside your modal by setting his visibility
} else {
// controller return was true so you can redirect or do whatever you wish to do here
}
}
});
Custom controller method could be something like this:
public function authenticate(Request $request)
{
$credentials = $request->only('email', 'password');
if (Auth::attempt($credentials)) {
// Authentication passed...
return true;
} else {
return false;
}
}
*Important note: Please note that I haven't fully coded evrything since stackoverflow is about solving problems not coding for others, so you will need to figure out how to select form data with js, and create the error msg and show it when controller returns false.
Also the controller is really basic, you can improve it with features such as controlling max-login attemps from a certain user, etc..*
You can use session variable $_SESSION['error']. And write a if condition over your login form like
if(isset($_SESSION['error']) echo "Your error message.")
And just unset the session variable just after that
I am working on CodeIgniter custom form, In this form, I have used CSRF token after form submit I want to check in controller after form submit if CSRF token is valid or not, can anyone please help me for this issue?
PHP Form code
<form role="form" data-parsley-validate="" novalidate="" class="mb-lg" action="?c=
<?php echo isset($controller) ? $controller : "welcome"; ?>&m=login" method="post">
<div class="form-group has-feedback">
<input name="email" id="exampleInputEmail1" type="email" placeholder="Enter email" autocomplete="off" required class="form-control">
<span class="fa fa-envelope form-control-feedback text-muted"></span>
</div>
<div class="form-group has-feedback">
<input name="password" id="exampleInputPassword1" type="password" placeholder="Password" required class="form-control">
<span class="fa fa-lock form-control-feedback text-muted"></span>
</div>
<div class="clearfix">
<div class="pull-right">
Forgot your password?
</div>
</div>
<?php
$csrf = array(
'name' => $this->security->get_csrf_token_name(),
'hash' => $this->security->get_csrf_hash()
);
?>
<input type="hidden" name="<?php echo $csrf['name'];?>" value="<?php echo $csrf['hash'];?>" />
<button type="submit" class="btn btn-block btn-primary mt-lg">Login</button>
</form>
CodeIgniter does this for you automatically. If it is not valid it will do a show_error with show_error('The action you have requested is not allowed.', 403);
Relevant functions can be found in the /system/core/security class, functions: csrf_verify() and csrf_show_error() (if invalid).
If you have understood by now, if you have csrf enabled in the config and you do not have the appropriate csrf hidden field or use form_open (which adds the field for you) then when you post the request it will fail with the above message. The same goes for AJAX requests - to automate this for ajax requests you can add this to the top of you page wherever there is an ajax request:
<script type="text/javascript">
token["<?php echo $this->security->get_csrf_token_name(); ?>"] = "<?php echo $this->security->get_csrf_hash(); ?>";
jQuery.ajaxSetup({data: token, type: "POST"});
</script>