I am trying to make a single page CRUD application with Laravel. I will use ajax to create, edit and delete my entity, and also to render partial views. The corresponding controller methods will process the information and return the views.
I want to register the routes so I can call the different methods when necessary. I don't see any other way:
However, registering them so I can do something like this {{ Form::open(['route' => ['cities.store', $city->id]]) }} will allow access via the URL, and I only want to make those routes accessible through the tools I am going to create in that one page CRUD.
I can only think of applying a before filter, but what would be the filter? Also, any other ideas on how I should approach this situtation?
I've had to do something similar with a web service I created. Basically, I wanted only my app to be able to access the routes I created.
What I ended up doing was adding a hashed key to each request being sent, then checking for this key value in the controller. So, only if the key is present and matches the one sent would you then process the request.
Or, if you're using forms, you could do something like the following:
//check if request was sent from our form
if ( Session::token() !== Input::get( '_token' ) ) {
return Response::json( array(
'msg' => 'Unauthorized access attempt'
) );
}
Hope this helps.
another way that doesnt need tokens but is less secure, you got to know what you need,
is using laravels request information
if (Request::ajax())
{
//your action
}else{
//error
}
note this only works when your application always uses ajax you could even type this in your before filter and add it to all needed routes
Related
I have ajax controler to store actions that are called through the AJAX from JS.
Here in every action I validate if request is made by AJAX and no other:
if (!$request->isXmlHttpRequest()) {
return new JsonResponse(array('message' => 'You can access this only using Ajax!'), 400);
}
Now the problem is that not every ajax controller action should be called by everyone, but rather depending on a role of the logged in user.
The request to action is made by AJAX from JS, but since actions are in controller I am still able to get logged in user object by $this->getUser() and to check if user has acceptable ROLE to execute the controller action by isGranted().
Example:
if (!$authorizationChecker->isGranted('ROLE_ADMIN')) {
return new JsonResponse(array('message' => 'This can be performed only by admin!'), 400);
}
Should I check ROLES from inside controller in every action or try to configure access_control for ajax routes in security.yml?
I have no idea what is the big difference between these two approaches, but would like to know which one would be more practical and could keep my ajax actions more secure.
Depends on the number of AJAX Controllers you have. If you have so many controllers those are to be allowed only for a certain role, access_control in security.yml is a good choice. Else you can have the condition in each controller.
For dynamic permission layer, where permission to be decided based on subject attribute(the viewing content), You might want to use voter.
is there a way to customize Laravel 5 resource URLs ?
For example, change user/1/edit to user/edit.
That's because I don't want anybody to see the id in the URL. I think it is database information and shouldn't be revealed.
The point is that I want to do this without changing my routes. On the other hands I want to do this by using resource routes I have and not by adding some new routes to them , as you know when you define a resource route in your project it automatically adds some predefined routes to the route table and you are forced to use them in the way they are. For example you have to send a GET request to user/{user} for showing the user. Now I want to have a URL like user/{username} for doing this without adding a new route, IS THAT EVEN POSSIBLE?
if there is a way for achieving this I appreciate it if you share it here.
Thanks a lot
Since in most cases id is an auto incremented value and guessable, better you can use any other unique column of users table here, e.g username and then using that column instead of id in resource controller. Suppose you've an unique username column in your table So, if you use that instead of id your call to user edit will be like:
{!! route('user.edit', $user->username) !!} // let's say username is shahrokhi
which is equivalent to
user/shahrokhi/edit
Now for example, in your resource controller to edit a user details code may be like:
public function edit($username)
{
$user = User::where('username', '=', $username)->firstOrFail();
// rest of your code goes here
}
And so on for other methods.
I'm working on a small project with CodeIgniter which handling some post data submitted from the admin form page.
I do transfer the post data to a method in my controller and send it to the database.
Its working all the time.
Im thinking, what if someone make an external form with the exact same inputs name and action attribute with mine in the admin page (I dont know how to figure the inputs name out but this is just my wonder), and try to post some data to the controller?
I try to use session but I wonder if there are any way to protect that kind of inject method?
you can try before your form_validator with
if( $_SERVER['HTTP_REFERER'] == base_url()){
//form validator
}
else{
$this->session->set_flashdata('warning', 'You try to enter from an external web without permission');
redirect(base_url(), 'refresh');
}
There are a couple of things you can do.
First, since this is an admin only page I assume you have some kind of login and user verification in place.
You can use session data to store the successful admin login.
//admin log in OK
$this->session->set_userdata('admin_logged_in', TRUE);
In the method that processes the form post, confirm the user is logged in
if($this->session->userdata('admin_logged_in') !== TRUE)
{
redirect('somewhere_else');
return; //here in case the redirect call doesn't work
}
Second, since you are 'posting' to this page confirm that is the method the server has received - it MUST be post. If you are using CI version => 3.0 the do this
if($this->input->method() !== 'post')
{
//somebody is trying to fool you
redirect('somewhere_else');
return; //here in case the redirect call doesn't work
}
If you are using an earlier version of CI (before 3.0.x) do this
if(strtolower($this->server('REQUEST_METHOD') !== 'post')
{
//somebody is trying to fool you
redirect('somewhere_else');
return; //here in case the redirect call doesn't work
}
You also might want to consider the case where the session info checks out but it was not a POST request. That is very suspicious to me and it might be wise to destroy the session before redirecting.
I am using laravel's RESTful resource routes and controllers.
I testing my api with PostMan and/or RestClient(firefox)
Everything was fine before I added laravel's controller validation. Now it respond with very strange responses like: status code 0, or even executes the code with not valid data. Or even shows strange results taken from the database (which are not included to the controller at all).
That's creepy.
For example:
public function store(Request $request) {
$this->validate($request, [
'room_id' => 'required|integer',
'body' => 'required'
]);
exit; // Stop the process after the validation...
// ... Logic to STORE the MESSAGE in the database ...
return response(null, 204);
}
This store function must only validate the data and respond with an error if validation fails,
But when I execute it from PostMan, It returns response with list of all rooms which belongs to this user. This is creepy, I cannot realize why this is happening.
When I use the jQuery.ajax() method with the same request options, it works fine. It validates the data and stores the message in the database.
Question : Is there a way to deal with postman?
Question : Is PostMan dangerous? Since the server respond with database info (which is not included to the controller responses).
If you take a closer look at laravel's validation document it says that when data is submitted via HTML form,the validate method would redirect you to a previous page and the error would be flashed into the session, if the validation fails. Although, you will be able to access these error messages in your view using the $error variable. Therefore you will need to submit the data via ajax in-order to get the JSON error message.
When validatioin failed, Laravel needs to know you are sending ajax request or you explicitly want json respond, otherwise it redirects you to previous page.
You can check my answer here
https://stackoverflow.com/a/38478362/6246592
G'day,
I'm having issues with PUT requests made via Chrome Postman to a controller, the PUT data is not present, POST data works fine.
I had performed a composer update prior to ensure that the latest version of vendor products where available and even removed bootstrap/compiled.php.
Is anybody else having similar issues?
The update function with both section_id and data being empty in the response:
public function update($id)
{
$section_id = Input::get('section_id');
$data = Input::all();
return Response::json(array('id' => $id, 'section_id' => $section_id, 'data' => $data));
}
I've debugged the code all the way to ParameterBag.php and $this->request's parameter list is empty, I'm not sure what's supposed to contain any values but all through the code the input values are empty. Not sure what to do now, short of using post instead of put.
PUT parameters don't work "out of the box" because PHP itself has some security restrictions around them. See: http://www.php.net/manual/en/features.file-upload.put-method.php
Laravel does implement a common workaround for this, though.
In Postman (or your form, or curl, or whatever client you're using), simply add a URL parameter name: "_method" value: PUT
Example 1:
?_method=PUT
Example 2:
<input type="hidden" name="_method" value="PUT" />
Laravel uses the symfony Http Foundation which checks for the _method variable and if it's present it routes based on its value, instead of the actual HTTP method used.
You have to send a POST request with adding an extra parameter _method with value PUT and it will works fine.