Laravel Share Variables between multiple Controllers - php

I'm using the AppServiceProvider to share specific admin data with all related views.
Now I'd like to share admin data also with all admin related Controllers to replace Auth::guard('admin')->user()->firstname by $admin->firstname.
$id = Auth::guard('admin')->user()->id;
$admin = Admin::findOrFail($id)->first();
How can I share this piece of code with all related Controllers to get for example admin firstname via $admin->firstname?

I would go about creating a global middleware
php artisan make:middleware AdminCarrier
In the middleware, you can add the $admin variable to the $request bag and access it via the Controller.
class AdminCarrier
{
public function handle($request, Closure $next)
{
$id = Auth::guard('admin')->user()->id;
$admin = Admin::findOrFail($id)->first();
$request->request->add(['admin' => $admin]);
return $next($request);
}
}
In the controller, you can access it via:
$request->admin
Make sure the middleware is global by registering it at Http/Kernel.php

Related

Access $user variable inside of Laravel middleware

I have a Laravel application that I have integrated with Xenforo so I can use Xenforo as the main user system behind the application. All of that is working properly, but my next challenge is trying to create middleware that takes the users' Xenforo permissions and restricts access to certain pages on the Laravel application.
I have a $user variable that I am passing to all of my views, and that contains all of the necessary user data that I need. I'm curious how I would go about accessing that same $user variable within my middleware to pull out their Xenforo permissions?
I have researched passing variables through the routes which I can access in the middleware. However, I am not looking to pass an actual parameter through the url to accomplish the task.
My BaseController contains the following and passes the $user variable to all of my views.
class BaseController extends Controller
{
public function __construct()
{
// Setting up the Xenforo enviornment
$dir = __DIR__;
require_once('../public/forum/src/XF.php');
\XF::start($dir);
$app = \XF::setupApp('XF\Pub\App');
// Retrieving the user_id of the current authenticated user
$session = $app->session();
$user_id = $session->get('userId');
// Looking up a users information by their user_id
$finder = \XF::finder('XF:User');
$user = $finder->where('user_id', $user_id)->fetchOne();
// Passing the user to every view
View::share('user', $user);
}
}
Here is the middleware and how I'm trying to get it to operate. My biggest issue is trying to get access to the $user variable that I am originally passing above.
class CheckRole
{
/**
* Handle an incoming request.
*
* #param \Illuminate\Http\Request $request
* #param \Closure $next
* #return mixed
*/
public function handle($request, Closure $next)
{
// I would like to find a way to access the $user variable here
if ($user->is_staff == true)
{
return $next($request);
}
else
{
//Restrict access and redirect
}
}
}
Using default Laravel users are accessible via the Auth::user() facade. The data there is filled via the Authenticate middleware.
In your case I'd suggest you use a similar strategy by implementing a middleware which logs the user in (the logic you now have in your controller) and then implement another middleware for checking roles. Beware when registering both middlewares, so the middleware which does the logging is executed first.
You could even go as far as to leverage the Auth facade yourself to manually log the user in and to store your custom user data like so.
You can do it by put your user data to session like this in your controller.
$session->put("user_data", $user);
access it from middleware
$app->session()->get("user_data");

In laravel middleware the parameter request id is missing

I have a Laravel controller with destroying method and middleware with name CheckRole.
public function destroy(Request $request, $id)
{
// code to delete item
}
I am unable to use the $id in middleware CheckRole.
class CheckRole
{
public function handle($request, Closure $next)
{
}
}
And
$request->id and
$request->route('id')
are also not working with the middleware.
How to fix this?
Getting URL Parameters in Middleware
class CheckRole
{
public function handle($request, Closure $next)
{
$id = $request->route()->parameter('id');
}
}
The $id in the destroy function is the id of the resource you want to delete, so that will never be the authenticated user id a better option for checking the role might be an authorization policy instead of a middleware.
Or get the authenticated user id by using: auth()->id() or $request->user()->id
You can also add a method in your User model, and check like that for example:
class User ...
public function isAdmin()
{
return $this->role === 'admin';
}
In the middleware
$request->user()->isAdmin();
--- EDIT
So if you use a resource when you defined your route for example:
Route::resource('user', 'UsersController');
Then in your middleware you can access the id of the user like this:
$request->user
If your route is like this:
Route::delete('/users/{user}', 'UsersController#destroy');
Then again you can get it using the named parameter $request->user. Make sure that whatever you use on your route in the {} that's the name of the parameter you use to get the id from.
There's no real safe way to do this as the user can just change the ID within the form submitted, unless you just want users who can sign in to be an admin. If this is true I would use #nakov's suggestion.
If you want to have a full permission system with roles, etc I would suggestion: https://github.com/spatie/laravel-permission
A good tutorial can be found here but please do not change anything it states with the password: https://scotch.io/tutorials/user-authorization-in-laravel-54-with-spatie-laravel-permission

Showing subpages based on a session in Laravel 5.8

I am begginer in Laravel. I am use Laravel 5.8 in my project.
I need to do something so that a specific route can be viewed by a user with a php adult = 1 session.
I have route:
Route::get('/', 'FrontendController#index')->name('index');
Route::get('/sample1', 'FrontendController#sample1')->name('sample1');
The SAMPLE1 view is for users with php adult = 1 session.
If the user does not have such a session - it must be automatically redirected to # index
How can you do this?
You can achieve this by creating a custom middleware, take a look at the documentation here:
https://laravel.com/docs/5.8/middleware
Instead of using session, you can maintain a user is adult or not on the users table, which means you can access this info via authenticated user (which is available throughout the whole app).
For e.g. in your app, use php artisan make:auth and this will scaffold out everything you need to for a register/login system. Before you run the migration, add a new field to the create_users_table migration, e.g. $table->boolean('adult')->default(false);
Then once the migration is ran, you can create a new middleware using: php artisan make:middleware CheckAdult with something like this:
<?php
namespace App\Http\Middleware;
use Closure;
class CheckAdult
{
public function handle($request, Closure $next)
{
if (!auth()->check() || !auth()->user()->adult) {
return redirect('/');
}
return $next($request);
}
}
The above middleware will redirect anyone who is not logged in or have adult = 0 back to index page, otherwise continue with their request.
Then register the middleware and use it in the routes; as per the documentation.
you can use auth and middleware to achieve this. the simple logic would be something like this: $id = Auth::user()->adult; in your controller to check for users. ofcorse adult is a field in your table.
//on top of your controller place this
public function __construct()
{
$this->middleware('auth');
}
//control logic to check user
if($adult==1){
//perform unique task
}else{
return redirect('/')->with('message','You are not permitted')
}

modify Laravel Auth registration page

I am trying to modify the Laravel Auth registration system in that I'd like to require that a token parameter be provided in order for the user to be able to access the registration page (ie http://website.dev/register/{tokenhere}). Below is the pertinent code:
From my routes\web.php file:
Route::get('/register/{token}', function() {
//
})->middleware('token');
From my \App\Http\Middleware\CheckToken.php file:
<?php
namespace App\Http\Middleware;
use Closure;
class CheckToken
{
public function handle($request, Closure $next)
{
if($request->token != 'test') { #just hard coding something here for testing purposes
return redirect('home');
}
return $next($request);
}
}
I also added 'token' => \App\Http\Middleware\CheckToken::class to the $routeMiddleware array in \App\Http\Kernel.php
However, I go to http://website.dev/register and I'm able to access the page, despite not providing a token parameter. I can also see that if I provide the 'test' parameter that the middleware is looking for (http://website.dev/register/test), I get a blank page.
Hoping someone can point me in the right direction. I'm quite new to MVC and Laravel. Thanks for your time!
You can just create custom route, like /register/{token} and handle this token in the controller. Maybe even set in middleware group if you want.

How can I require authentication in Laravel 5 on a conditional basis?

I have an application which uses Laravel 5's out of the box authentication. I need to require authentication on the show method of a controller ONLY when the field called "approved" is equal to 1.
How can I require authentication using middlewares on a conditional basis such that unauthenticated users can access entries whose approved column is equal to 1, but only authenticated users can see entries where approved is equal to 0.
My constructor currently looks like this:
public function __construct(){
$this->middleware('auth', ['only' => ['edit', 'destroy', 'approve', 'markRecovered']]);
}
You may create your own middleware instead of using Laravel's default auth middleware and in that case, you may create a middleware such as 'checkApproval' using something like this:
php artisan make:middleware checkApproval
Then in your app/Http/Middleware directory you'll find the new middleware created and it'll contain the basic structure including handle method, so now you may erite code inside this middleware's handle method to check the user's state and the approved field and then either redirect to login page if condition doesn't match or allow access. here is a basic idea:
use Illuminate\Contracts\Auth\Guard;
class CheckPermission implements Middleware {
protected $auth;
public function __construct(Guard $auth)
{
$this->auth = $auth;
}
public function handle($request, Closure $next)
{
if($this->auth->guest() && !$this->checkApproval($request))
{
return redirect('login');
}
return $next($request);
}
protected function checkApproval($request)
{
// Get the auth/logged in user
// $user = $request->user();
// Get a parameter from route
// $id = $request->route()->parameter('id')
// Check the approved field here and return true or false
}
}
Now assign the middleware a short-hand key in your app/Http/Kernel.php file. By default, the $routeMiddleware property of this class contains entries for the middleware included with Laravel. To add your own, simply append it to this list and assign it a key to use in your route/controller, for example, checkApproval so in the place of auth you may use checkApproval for the the method view in your controller.
This is an abstract idea, but you can implement one of your own now so check the documentation for more information.

Categories