How to resolve TokenMismatchException in Laravel 5 App - laravel-5.1

I have developed a laravel 5 app and everything works fine except that I occationally get TokenMismatchException in VerifyCsrfToken.php line 53. I can't seem to figure out the cause. This happens mostly during login. I used the laravel built-in trait to implement authentication. Below is my sample logout method.
public function getLogout()
{
Auth::logout();
Session::forget('cart_id');
Session::forget('is_supervisor');
Session::forget('is_manager');
return redirect(property_exists($this, 'redirectAfterLogout') ? $this->redirectAfterLogout : '/');
}
Each time the exception occurs, I have to reload the page and login again before this works. Below is a sample of my login form:
{!! Form::open(array('class' => 'form-horizontal', 'role' => 'form')) !!}
<div class="form-group">
{!! Form::label('username', trans('home.username'), array('class' => 'col-sm-3 control-label')) !!}
<div class="col-sm-9 col-lg-5">
{!! Form::text('username', null, array('required' => 'required', 'class' => 'form-control input-sm')) !!}
</div>
</div>
{!! Form::close() !!}
When I check the page source, the csrf token is always available. What could possibly be the problem. I am using laravel 5.1.* and SESSION_DRIVER=file in .env.
Edit
// Authentication routes...
Route::get('auth/login', 'Auth\AuthController#getLogin');
Route::post('auth/login', 'Auth\AuthController#postLogin');
Route::get('auth/logout', 'Auth\AuthController#getLogout');

CSRF Protection (Cross-Site-Request-Forgery) saves you from unwanted actions on web application.
The token is generated when rendering form and expired after some time.
If you have the form opened too long, you get TokenMismatchException.
Did you notice the problem shortly after reload page (form)?
Try to add
{{ csrf_field() }} to your form and check if it helps.

Related

ViewModel data being passed in address bar

I have my change password controler.
The user changes the password and clicks submit.
I have my viewmodel of person p.
I am not passing it at all to my success page.
return View("succsessFulLogin");
And still I am getting
http://localhost:50010/Password/ChangePassword?AccountName=username&CurrentPassword=currentPassValue&NewPassword=newPassValue&NewPasswordCheck=newCheckPassValue
In the address bar
this is my code on the page:
#using (Html.BeginForm("ChangePassword", "Password", FormMethod.Get))
{
#Html.HiddenFor(model => model.AccountName)
<br />
<div>
<h4>#Html.LabelFor(m => m.CurrentPassword)</h4> #Html.PasswordFor(m => m.CurrentPassword, new { onkeydown = "capLock(event);" } ) #Html.ValidationMessageFor(m => m.CurrentPassword)
</div>
<br />
<div>
<h4>#Html.LabelFor(m => m.NewPassword)</h4> #Html.PasswordFor(m => m.NewPassword, new { onkeydown = "capLock(event);" }) #Html.ValidationMessageFor(m => m.NewPassword)
</div>
<br />
<div>
<h4>#Html.LabelFor(m => m.NewPasswordCheck)</h4> #Html.PasswordFor(m => m.NewPasswordCheck, new { onkeydown = "capLock(event);" }) #Html.ValidationMessageFor(m => m.NewPasswordCheck)
</div>
<br />
<p>
<button class="btn-lg" type="submit">#Global.SAVE</button>
</p>
}
I disagree with osman Rahimi.
Using HTTP POST is in no way more secure than HTTP GET! As long as you're passing everything as clear text over http, you can read anything passed to and from the server, even if it isn't shown in the address bar. If you want to check me yourself, all you have to do is download fiddler, check the request and responses your page generates and see for yourself.
The proper way to transmit passwords on the net is to make sure you're using SSL and hashing the passwords. I am by no means an expert on the subject, but I think you'll find need in these answers:
Securely Transfer User Entered Password
How should password be transfered for logon in Asp.net Identity
How to securely save and send login username/password?
when you are using HTTP GET the browser send data in URl and in this way you have limitation up to 2048 characters.
know more about HTTPGET and HTTPPOST
to keep your data secure and protected change your method To POST Like this :
#using (Html.BeginForm("ChangePassword", "Password" FormMethod.Post, null))
{}
then Add [HTTpPost] to your Action Method in your controller , like :
[HttpPost]
public ActionResult ChangePassword(yourmodel model){}

Why won't my Angular app send params to my Entangle rails controller?

In an effort to learn about realtime apps, I am trying to create a basic messageboard using Entangled.
I have an Angular app and a Rails backend with a Messages Controller that includes Entangled::Controller. This Rails controller successfully receives a request when a form is submitted from the Angular app - the form is submitted using Entangled. (On clicking submit, a function is triggered in an Angular controller which should create a new message in the backend and update all clients subscribed to that backend.)
I know the Angular function is being triggered on clicking submit, and I know the function receives the correct information from the form: console.log($scope.message) displays {socket: "ws://message-board-olliehm.c9users.io:8080/messages", username: "ggg", content: "gggggg"} where I submit "ggg" in the username field and "gggggg" in the content field.
The problem is that these fields are not arriving at the Rails controller. When I click submit, the correct action is triggered in the Rails controller, but the params don't contain the right information: p params in def create returns {"controller"=>"messages", "action"=>"create"}, with no "message" hash and no "username" or "content" keys.
I cannot work out what Entangled is doing with the username and content fields.
Redis is new to me so I'm not sure if the problem is there. I have Redis installed and the redis-server is running as required by Entangled. I have a redis initializer as below, which in the Rails console is successfully connecting and letting me put data in the database:
$redis = Redis.new(:host => $IP, :port => 6379)
Here's my Angular controller:
var controllers = angular.module('controllers');
controllers.controller('MessageboardController', ['$scope','Message', function($scope,Message){
$scope.message = Message.new();
$scope.post = function() {
console.log($scope.message);
$scope.message.$save(function() {
$scope.$apply(function() {
$scope.message = Message.new();
});
});
};
Message.all(function(err, messages) {
$scope.$apply(function() {
$scope.messages = messages;
});
});
}]);
Message here refers to this factory:
messageboard.factory('Message', function(Entangled){
return new Entangled('ws://message-board-olliehm.c9users.io:8080/messages');
});
And here's my Angular view:
<h1>Messageboard</h1>
<section class='row' ng-if='messages'>
<ul>
<li ng-repeat='message in messages'>
{{message.username}}
{{message.content}}
</li>
</ul>
</section>
<section class='row'>
<form ng-submit="post()">
<div class='form-group'>
<label for='username'>Message as</label>
<input ng-model='message.username' name='username' type='text'>
</div>
<div class='form-group'>
<input ng-model='message.content' name='message' type='text' placeholder='Write your message here'>
</div>
<div class='form-group'>
<input type="submit">
</div>
</form>
</section>
Advice would be hugely appreciated - this has caused prolonged frustration and I'm very keen to get stuck into creating something with realtime updates.
After much trial and error I realised the empty params apparently received by the backend controller were misleading. The params arrive properly and a new message object is created and broadcast as long as I do the following to the raw params the controller receives:
params.require(:message).permit(:content,:username)
i.e. exactly what you'd do with the form params arriving as you'd expect. The weird thing for me was that params doesn't include a 'message' hash until you require that hash as above. I guess this is something to do with it not being a regular http request, though a proper explanation would be appreciated...

The usage of Form on Laravel 5.1 shows only text

I use the laravelcollective/html form, and i opend the form
{!! Form::open(['role' => 'form']) !!}
and closing
{!! Form::close() !!}
and of course the contect inside, the problem is that the output is like text
<form method="POST" action="http://localhost/Users/public" accept-charset="UTF-8" role="form">
There is no problem in your form but make sure you are using it in filename.blade.php, .blade.php is important or you can always use simple html5 forms in any case :)

What is the syntax to embed a server control in an ASP text box? I can't find a working example anywhere

I'm new to ASP MVC and I'm completely stuck.
All I want to do is have a control like this:
<td><asp:TextBox ID="txbFirstName" runat="server" Value=""></asp:TextBox></td>
But have it populated by a value from a controller.
This syntax is what I was expecting would work:
<td><asp:TextBox ID="txbFirstName" runat="server" Value="<% Model.FirstName%>"></asp:TextBox></td>
But obviously it doesn't. I hope from that you can tell what I'm trying to do (populate the value of the text box with a server control) but that won't work. Is this not possible using ASP:Textboxes? Do I need to use HTML boxes instead?
Apparently in ASP 4 MVC the <% %> tags are no longer used and I cannot find a working example anywhere. I thought this would be a simple google but I've been stuck for hours.
Thank you for any help you can provide.
Microsoft MVC doesn't use server side controls.
You should use HTML Helpers and Model Bindings with Razor view engine (better than ASP.NET view engine).
In the view:
#Html.EditorFor(model => model.Firstname)
A simple Login form:
#using (Html.BeginForm("LoginAction", "LoginController"))
{
#Html.LabelFor(model => model.User, "Your UserName")
#Html.EditorFor(model => model.User)
#Html.LabelFor(model => model.Password, "Your Password:")
#Html.PasswordFor(model => model.Password)
<button type="submit">Submit</button>
}
See http://www.asp.net/mvc/overview/getting-started

Disable Required Validation Specific Field in the View ASP.NET MVC 4

if someone could give me some hint I would appreciate.
I'm searching for a while, and I even found a post I thought it would solve my problem, but it didn't.
Disable Required validation attribute under certain circumstances
Basically I have a simple User.cs model where I have username, FirstName, LastName and SignupDate
All have the required annotation and I would like to solve this without erasing the Required tag.
After I generate the view, I erase in the view the html code for the SignupDate:
<div class="editor-label">
#Html.LabelFor(model => model.SignupDate)
</div>
<div class="editor-field">
#Html.EditorFor(model => model.SignupDate)
#Html.ValidationMessageFor(model => model.SignupDate)
</div>
When I click submit it does not work.
Also if I do the suggested in the other post
<div class="editor-label">
#Html.LabelFor(model => model.SignupDate)
</div>
<div class="editor-field">
#Html.TexBoxFor(model => model.SignupDate, new { data_val = false })
</div>
If I leave it as blank also does not work..
Any suggestions? Thanks!!
You can disable client validations on the view and remove the errors on the modelstate for those entities you don't want to validate the value.
In my case I wanted to change a Password only if the user typed one. Using Html.HiddenFor was not a good approach due to sends the password to the client every time, and password shouldn't be sent.
What I did was to disable the client validations on the view
#model MyProject.Models.ExistingModelWithRequiredFields
#{
ViewBag.Title = "Edit";
Html.EnableClientValidation(false);
}
That allows me to submit the form even with empty values. Please note that all client validations are ignored, however server validations still run, so you need to clear those you don't need to be executed. In order to do this, go to the action in the controller and remove the errors for each property you need to
public ActionResult Edit(ExistingModelWithRequiredFields updatedModel)
{
var valueToClean = ModelState["RequiredPropertyName"];
valueToClean.Errors.Clear();
if(ModelState.IsValid)
{
...
//Optionally you could run validations again
if(TryValidateModel(updatedModel)
{
...
}
...
}
...
}
I think this should solve it, assuming model.SignupDate holds a value:
<%: Html.HiddenFor(model => model.SignupDate) %>

Resources