Laravel Middleware access protected values - laravel

i wrote my own User-Role System, but i dont know how to implement the verification in my middleware routes.
The middleware class is calling on every request.
I recive the $request->user() but i can not access the attributes to verify if the user has the correct permissions.
My middleware controller looks like this:
namespace App\Http\Middleware;
use Closure;
use Activation;
use Cartalyst\Sentinel\Laravel\Facades\Sentinel;
class AccountMiddleware
{
/**
* Handle an incoming request.
*
* #param \Illuminate\Http\Request $request
* #param \Closure $next
* #return mixed
*/
public function handle($request, Closure $next)
{
$user = Sentinel::findByCredentials([
'login' => $request->user()->attributes['email']
);
...
return $next($request);
}
}
It doesnt work.
If I trie to dump the $request->user() i can see all properties but there are protected.
What do i need to change, to make it work?

Accessing Eloquent model properties is done via accessors, in this case via the __get magic method. So you don't need to access them through the $attributes property array, all you need is this:
$request->user()->email;
The above will return the user email because the Illuminate\Database\Eloquent\Model::__get method already fetches the specified attribute automatically.
If you like, you can even define your own Accessors or Mutators to modify attribute values when reading or writing them to the database.

Related

Laravel - extending Illuminate\Http\Request and using session

I've extended the Illuminate\Http\Request class and am passing it along to my controller.
use Illuminate\Http\Request;
class MyRequest extends Request
{
...
}
Controller
class MyController
{
// Doesnt work
public function something(MyRequest $request) {
var_dump($request->session())
}
// Does work
public function something(Illuminate\Http\Request $request) {
var_dump($request->session())
}
}
So when I'm trying to get session $request->session() I get RuntimeException - Session store not set on request.
I feel it has something to do with not running middlewares on my custom request but I dont know how to make it work. Helping or pionting to the right direction would be much apreciated.
To give a little bit more info. I'm trying to make a wizard. Several pages where content of one page depends on choices on previous pages. I'm storing the data in session and on the final page I do "stuff" with it and clear the session storage of current user.
Because it a lot of lines of code and since session instace lives on request I though it would be elegant to hide all those line it in custom request and in controler simply call $myRequest->storeInputs()
This is what seemed to me as "most elegant" in this particular case so I would prefer to finish it this way but I'm also open to a different solution if there is a better aproach.
Summary: basically where should I hide all those lines which are storing and retriving data from sesison?
Solution: I actually solved it by extending FormRequest since it was solution which was the best fit for what I was trying to do. However I accepted the one offered answer since I believe it is generally better solution and I would use it if not for this very particullar case.
The classic Laravel request already got a bunch of settings you didn't catch on your custom request. To achieve that, you should setup a middleware (maybe global in your use-case) which replaces old request in Laravel's container by yours.
<?php
namespace App\Http\Middleware;
use App\Http\MyRequest;
use Closure;
use Illuminate\Contracts\Foundation\Application;
use Illuminate\Http\Request;
class CustomizeRequest
{
/**
* #var \Illuminate\Contracts\Foundation\Application
*/
protected $app;
/**
* #var \App\Http\MyRequest
*/
protected $myRequest;
/**
* #param \Illuminate\Contracts\Foundation\Application $app
* #param \App\Http\MyRequest $myRequest
*/
public function __construct(Application $app, MyRequest $myRequest)
{
$this->app = $app;
$this->myRequest = $myRequest;
}
/**
* Handle an incoming request.
*
* #param \Illuminate\Http\Request $request
* #param \Closure $next
* #return mixed
*/
public function handle(Request $request, Closure $next)
{
$this->app->instance(
'request', Request::createFrom($request, $this->myRequest)
);
return $next($this->myRequest);
}
}

how to check whether a restaurant is verified in laravel

I am new to laravel and trying to make a panel for food delivery
I have used Laravel default Registration and Login for User Category--Restaurant
and then after user login , the user can Add restaurant details using route (/add_details)
once the user has added restaurant details the user should not be able to go to that route (/add_details)
this will depend on a column in restaurant table (is_verified)
how do i check that
I was thinking of using a Laravel middleware
but then i was stuck how laravel middleware $request variable works
how can i get column value in middleware and verify it
or if any other simple but effective solution
as
i will be using it in sidebar.blade.php as well
so that i can hide the menu
I made a middleware and added it to kernel.php and is using it in routes
Its working fine
but i want to ask is this the right way i have done it
Route::get('/manage_cuisines', 'RestaurantCuisineController#create')->name('manage-cuisines')->middleware('restaurant_verified');
<?php
namespace App\Http\Middleware;
use Closure;
use Auth;
use \App\User;
use \App\Restaurant;
class CheckRestaurantVerification
{
/**
* Handle an incoming request.
*
* #param \Illuminate\Http\Request $request
* #param \Closure $next
* #return mixed
*/
public function handle($request, Closure $next)
{
$restaurant = Restaurant::find(User::find(Auth::id())->restaurant_id);
if($restaurant->is_verified == 0)
{
return redirect('home');
}
return $next($request);
}
}

How to remove key from input?

I am passing JWT token in request object for verification. After verifying JWT, I want to remove the token key from input otherwise it reaches model and generates error.
One way is to use something like $request->except('token') but I have to write this everywhere.
Second way is to use a middleware to remove this key:
<?php
namespace App\Http\Middleware;
use Closure;
class InputCheck
{
/**
* Handle an incoming request.
*
* #param \Illuminate\Http\Request $request
* #param \Closure $next
* #return mixed
*/
public function handle($request, Closure $next)
{
$request->request->remove('token');
return $next($request);
}
}
The above statement is not removing token. Can't find anything on how to remove key from $request. Middleware is working fine.
Try the except method in the middleware:
$response = $request->except(['token']);
return $next($response);
https://laravel.com/docs/5.6/requests#retrieving-input under Retrieving A Portion Of The Input Data

New registered user to be redirected to the password reset screen

I'm quite new to Laravel and have been stumped on a problem for 2 days - I'd be grateful for some guidance.
I'm using the default out-of-the-box User authentication system with Laravel 5.3. A new user is created automatically behind the scenes by an existing Admin user - I will in time hide the user registration page. I have also successfully set up middleware to check if a user is newly registered (by looking for a null 'last_logged_in_date' that I've added to the migration).
All I want to happen is for a new registered user to be redirected to the password reset screen that ships with Laravel (again, in time I will create a dedicated page). I would like this to happen within the middleware file. So far, my middleware looks like this:
<?php
namespace App\Http\Middleware;
use Closure;
use App\Http\Controllers\Auth;
class CheckIfNewUser
{
/**
* Handle an incoming request.
*
* #param \Illuminate\Http\Request $request
* #param \Closure $next
* #return mixed
*/
public function handle($request, Closure $next)
{
$user = $request->user();
if (! is_null($user->last_logged_in_date )) {
return $next($request);
}
// This is where I'm stuck!!!
}
}
I'm not sure what code to enter at the location indicated by the comments above. I've tried sendResetLinkEmail($request); etc and have imported what I though were the correct classes but I always end up with a Call to undefined function App\Http\Middleware\sendResetLinkEmail() message irregardless of what I 'use' at the top of my class.
Where am I going wrong? Thanks!
Well that happens because you have not defined your sendResetLinkEmail($request) function yet. You can do it like this, or you can create a new class with that and then call the class.
Call the trait SendsPasswordResetEmails and then access it with $this since traits are not classes and you cannot access their members directly.
<?php
namespace App\Http\Middleware;
use Closure;
use App\Http\Controllers\Auth;
use Illuminate\Foundation\Auth\SendsPasswordResetEmails;
class CheckIfNewUser
{
use SendsPasswordResetEmails;
/**
* Handle an incoming request.
*
* #param \Illuminate\Http\Request $request
* #param \Closure $next
* #return mixed
*/
public function handle($request, Closure $next)
{
$user = $request->user();
if (! is_null($user->last_logged_in_date )) {
return $next($request);
}
// This is where I'm stuck!!!
//EDIT
//return $this->SendsPasswordResetEmails->sendResetLinkEmail($request);
return $this->sendResetLinkEmail($request);
}
}

Validation of array in FormRequest in Laravel 5

I use Ajax to send form data to a resource controller (Laravel 5). However I send my form fields with this call as an Array (no direct form field vars)
I have setup a Request with the rules which need to be validated.
However the default behaviour of this kind of validation is that it only looks at the direct field variables inside the Request object. So for instance if I would send: input name="firstname", I simply would have to set
public function rules()
{
return [
'firstname' => 'required|alpha|between:1,128'
];
}
But now, how can I validate an array inside the Request object? So for instance, what if I would send input name="nameArray['firstname']"?
So what I want to do is to modify the Request object before it is sent to the validation. Or maybe there is a better way to deal with this. I know one can loop through the object inside the rules method like this:
foreach($this->request->get('nameArray') as $key => $val)
{
}
But that doesn't help, as the Validator of Laravel will use the direct fields set in the Request object. So I can't change that here.
I want to get the individual form fields out of the array, and put them back directly in the Request object, so Validation can be done with the same way of setting the rules etc.
Btw, I use this method of Validation, by calling the Request method inside the resource controller where, in this example, I want to store the input.
public function store(CreateStudentRequest $request)
{
}
I would create a middleware for sanitizing the request object.
class SanitizeMiddleware
{
/**
* Run the request filter.
*
* #param \Illuminate\Http\Request $request
* #param \Closure $next
* #return mixed
*/
public function handle($request, Closure $next)
{
// here do the sanitation needed to
// make the request object work with the validator
}
}
I would probably create the sanitation methods on its own class and just inject it through the controller to keep the code clean.
Also you can also do the sanitation in the Javascript side if that's easier for you.
Well indeed, Middleware seems to do the Job. Came across another method where the class Request was extended with new validator method. However, to me it looks the middleware functionality was meant for this.
The Class I created finally looks like this
class SanitizeFormRequest
{
/**
* Handle an incoming request.
*
* #param \Illuminate\Http\Request $request
* #param \Closure $next
* #return mixed
*/
public function handle($request, Closure $next)
{
if(isset($request['ajaxData']))
{
$input = $request['ajaxData'];
foreach ($input as $key => $value) {
$request->merge([$key => $value]);
}
}
return $next($request);
}
}
I registered it as $routeMiddleware inside the kernel.php
And applied on the concerning routes.
Route::group(array('middleware' => ['auth', 'form.request']), function(){
Thanks.

Resources