how to get auth information in AppService provider? - laravel

I'm trying to give a condition is user suspend, user should redirect to login page if user in login state.
I have tried to give a check in AppServiceProvider like below
public function boot()
{
if(auth()->user()->is_deleted === true) return redirect('/logout');
}
Problem is in AppServiceProvider I'm not getting any auth information. How I can solve this problem ?

You can do this better with Middlewares,
Create a middleware CheckIfDeleted
php artisan make:middleware CheckDeleted
Open the CheckIfDeleted and update the handle method:
public function handle(Request $request, Closure $next)
{
if(auth()->check() && auth()->user()->is_deleted === true){
Auth::logout();
$request->session()->invalidate();
$request->session()->regenerateToken();
return redirect('some error page?');
}
return $next($request);
}
Open the Kernel.php (app/http folder), then add the new middleware in the web section (protected $middlewareGroups):
\App\Http\Middleware\CheckIfDeleted::class,
I also recommend you implement the softDelete of laravel, you can use this guide from stack: Laravel Soft Delete posts
In this case if the user is deleted, they will get an error message, and you will still keep the record of the user :)

Related

Auth::check fails in middleware

Can somebody explain why this strange behavior of Laravel is happening? Basically, I am trying to create a middleware for my application
public function handle(Request $request, Closure $next)
{
if (auth()->check()) {
$expires = Carbon::now()->addMinute(2);
\Illuminate\Support\Facades\Cache::put('user-is-online-' . Auth::user()->id, true, $expires);
}
return $next($request);
}
}
But auth()->check it is keep failing and not returning true , (user is authenticated) , auth()->check is working in other places like web routes and controllers method but why not here ?
If you are using auth middleware to protect your routes, then make sure this auth middleware is set to run before your middleware, otherwise auth()->check() will return false. Try php artisan route:list and check the orders of middlewares for your specified route.

laravel: how to stay login until a condition becomes false?

I have a field (can_login) in my users table.
normally,users can login. and logout with this code:
Auth::logout();
I want, when each time a logged-in user refresh a page,
laravel check can_login in user table.
if can_login is false, then auto logout.
I try this in RouteServiceProvider
public function boot()
{
parent::boot();
if(auth()->user()->can_login){
return route('logout');
}
}
but auth()->user() is always empty.
You can use a middleware or add a check to your existing authentication middleware.
On each request it passes through a middleware to check if user is authenticated and after that auth()->user() will not be empty.
Simplest solution would be to create a middleware in app/Http/Middlewares/CheckUserCanLoginMiddleware.php
class CheckUserCanLoginMiddleware
{
public function handle(Request $request, Closure $next)
) {
if ($request->user()->can_login ?? false) {
Auth::logout();
return $this->sendUnauthorizedResponse();
}
return $next($request);
}
}
And then register it as a routeMiddleware` in your bootstrap/app.php file.
The last thing you need is to use it to our routes middlewares after authentication middleware.

Laravel preventing user from accessing other users resource **url

I am passing a specific resource in the url, for ex.
https://www.example.com/{companyID}
And in the controller I can access the resource by
public function index($companyID)
{
// Code Here
}
I need to block users from changing the url and accessing other companyIDs from the system. Currently its open and is a security risk. I checked out Laravel Gate and Policy's but fail to see how this could be implemented for my case.
What I am really looking for is something in the AuthServiceProvider boot method that can check if the user really is the owner of the resource before continuing with the code.
Any help?
As mentioned before, you can do that by creating a Middleware that checks if your resource should be available to the logged in user.
See some details about middleware here
First, create a Middleware via php artisan, like this
php artisan make:middleware AuthResource
Next, add it to your App\Http\Kernel.php
protected $routeMiddleware = [
...
'AuthResource' => \App\Http\Middleware\AuthResource::class,
];
In your routes, you can now do the following:
Route::get('{companyID}', ['uses' => CompanyController#index, 'middleware' => 'AuthResource']);
That way, your AuthResource middleware is used whenenver the route is called.
In your App\Http\Middleware\AuthResource.php you have to change the code from
public function handle($request, Closure $next)
{
return $next($request);
}
to something that checks if the resource is available to the currently logged in user.
I assume that your companies table has a field user_id, which links the Company to a User. If your data structure is different, you need to change the code accordingly.
public function handle($request, Closure $next)
{
if ($request->route('companyID')) {
$company = Company::find($request->route('companyID'));
if ($company && $company->user_id != auth()->user()->id) {
return redirect('/');
}
}
return $next($request);
}
That way we check if the a route parameter with the name companyID exists, and if it does we check if it is available to the currently logged in user. If no companyID parameter is available, the page can be loaded without any restrictions.
That way you can copy/paste the code within the middleware for any parameters so that the middleware does work for multiple resources (not only companies).
This is can be done easily by middleware. But I’ll do this in more understandable way.
I assume that your user has one to one relationship with company.
So first create the relationship,
In your User model,
Public function company() {
return $this->hasOne(‘App\Company’);
}
Company model
Public function user(){
return $this->belongsTo(‘App\User’);
}
So, now make Authenticate by running php artisan make:auth . more details on Authenticate
And now in your controller,
public function index($companyID)
{
$current_user = Auth::user();
$user_company = $current_user->company; // get the current user's company details
If($companyID == $user_company->id){
// do something
}
}

Laravel 5 restrict access to pages using middleware

I am working on a laravel project and i need to restrict access to some pages such that only authenticated users can view that page.
To do this, created a middleware: php artisan make:middleware OnlyRegisteredUser
and registered it in the $routemiddleware inside App\Http\kernel.php as
'onlyregistereduser' => \App\Http\Middleware\OnlyRegisteredUser::class,
and this is the class. it redirects user to auth/login if not logged in
public function handle($request, Closure $next, $right=null)
{
$user = $request->user();
if ($user && $user->onlyregistereduser()) {
return $next($request);
}
return redirect('auth/login');
}
Here is my route:
Route::get('admin/poem', ['middleware' => 'onlyregistereduser:admin', 'uses'=>'PoemsController#poem']);
admin is a parameter passed to my middleware. It is taken from my user model which has an `enum' column as follows:
public function up()
{
Schema::create('users', function (Blueprint $table) {
//...
$table->enum('rights', ['admin', 'guest'])->nullable();
// ...
});
}
Now to restrict access to some of my controller methods, e.g create, i added a constructor to my PoemsController as shown:
public function __construct()
{
$this->middleware('onlyregistereduser');
}
My problem now is that this caused every single route to the PoemsController to redirect me to the login page. And again after login in, it doesn't take me to the page i intended to visit. it takes me instead to the home page. What i want is to restrict access to only some of the controller methods and not all of them and to be able to redirect to the intended page after user login.
I hope you understand my problem.
Any help will be greatly appreciated.
Remove the middleware from constructor, you don't have to add middleware to both route and costructor. That should solve your ". What i want is to restrict access to only some of the controller methods and not all of them" issue.
For othe issue modify your middleware like this
public function handle($request, Closure $next, $right=null)
{
$user = $request->user();
if ($user && $user->onlyregistereduser()) {
return $next($request);
}
$request_url = $request->path();
session()->put('login_refferrer', $request_url);
return redirect('auth/login');
}
and before redirect user after login
if(session()->has('login_refferrer')){
$url = session()->pull('login_refferrer');
return redirect($url);
}

Laravel 5.2 Redirect admin page after login as admin

Laravel 5.2 has been out for some time now. Yes, it has new auth function which is very good. Specially for beginners.
My question,
How to check if user is admin and then redirect safely to admin/dashboard properly? I know one way is to use admin flag in database but can any of you show some example?
go to AuthController.php and add this method
where role is the user role as defined in the database.
protected function authenticated($request,$user){
if($user->role === 'admin'){
return redirect()->intended('admin'); //redirect to admin panel
}
return redirect()->intended('/'); //redirect to standard user homepage
}
As in Laravel 5.3 / 5.4
Add following line to create_users_table migration.
$table->boolean('is_admin');
Add following method to LoginController.
protected function authenticated(Request $request, $user)
{
if ( $user->is_admin ) {
return redirect('/admin/home');
}
return redirect('/home');
}
Additional note don't forget to add the following lines to RedirectIfAuthenticated middleware:
public function handle($request, Closure $next, $guard = null)
{
if (Auth::guard($guard)->check()) {
// the following 3 lines
if (Auth::user()->is_admin) {
return redirect('/admin/home');
}
return redirect('/home');
}
return $next($request);
}
Otherwise if you e.g. type yourdomain/login and your logged in as admin it would be redirected to home instead of admin/home.
AuthController extends the AuthenticatesAndRegistersUsers trait, which has a public method named redirectPath. In my case I would extend that method on the AuthController and I'd put my logic there:
public function redirectPath()
{
if (Auth::user->myMethodToCheckIfUserHasAnAdminRoleLikeAnEmailOrSomethingLikeThat()) {
redirect('admin/dashboard');
}
redirect('home');
}
in Auth/LoginController there is protected $redirectTo = '/home';
change '/home' to '/loginin' for example, and create a new controller and in the controller get the information of the user and check if he is a admin or not and then redirect him to the proper page

Resources