My custom middleware doesn't work in Laravel - laravel

Something wrong with my custom middleware. It doesn't work. I have registered it in Kernel.php , the routeMiddleware array.
protected $routeMiddleware = [
'auth' => \Illuminate\Auth\Middleware\Authenticate::class,
'auth.basic' => \Illuminate\Auth\Middleware\AuthenticateWithBasicAuth::class,
'bindings' => \Illuminate\Routing\Middleware\SubstituteBindings::class,
'can' => \Illuminate\Auth\Middleware\Authorize::class,
'guest' => \App\Http\Middleware\RedirectIfAuthenticated::class,
'throttle' => \Illuminate\Routing\Middleware\ThrottleRequests::class,
// 'jwt.auth' => Tymon\JWTAuth\Middleware\GetUserFromToken::class,
'jwt.refresh' => Tymon\JWTAuth\Middleware\RefreshToken::class,
'upload.file' => \App\Http\Middleware\Upload::class,
'admin.settings' => \App\Http\Middleware\AdminChange::class,
];
And in my middle , I used dd to print sth
class AdminChange
{
/**
* Handle an incoming request.
*
* #param \Illuminate\Http\Request $request
* #param \Closure $next
* #return mixed
*/
public function handle($request, Closure $next)
{
dd('i\'m here');
config(['auth.providers.users.model' => '\App\Models\Useradmin::class']);
return $next($request);
}
}
And , my api group like this.
$api = app('Dingo\Api\Routing\Router');
$api->group([
'version' => 'v1',
'namespace' => 'App\Http\Controllers\Api',
],function($api){
$api->group([
'middleware'=>['admin.settings'],
'prefix'=>'ad'
],function($api){
include_once(base_path('routes/v1/admin/notice.php'));
});
$api->group([
'middleware' => ['api.auth']
],function($api){
});
});
I tried to rename the alias admin.settings to other names ,it still did not work.
I couldn't get i am here , it seemed the middleware didn't work. Does anyone help?

Related

Laravel 9 - ERROR: Auth guard [ admin] is not defined

I'm trying to create an Admin Login in Laravel Jetstream. I've created a separate admins table to store the login data. However, I get an error saying Auth guard [ admin] is not defined when I try to access the admin login page through http://localhost:8000/admin/login.
I tried php artisan config:clear and php artisan config:cache commands, but they didn't solve the issue.
auth.php
'guards' => [
'web' => [
'driver' => 'session',
'provider' => 'users',
],
'admin' => [
'driver' => 'session',
'provider' => 'admins',
],
],
'providers' => [
'users' => [
'driver' => 'eloquent',
'model' => App\Models\User::class,
],
'admins' => [
'driver' => 'eloquent',
'model' => App\Models\Admin::class,
],
],
'passwords' => [
'users' => [
'provider' => 'users',
'table' => 'password_resets',
'expire' => 60,
'throttle' => 60,
],
'admins' => [
'provider' => 'admins',
'table' => 'password_resets',
'expire' => 60,
'throttle' => 60,
],
],
web.php
Route::get('/', function () {
return view('welcome');
});
Route::group(['prefix' => 'admin', 'middleware' => ['admin:admin']], function () {
Route::get('/login', [AdminController::class, 'loginForm']);
Route::post('/login', [AdminController::class, 'store'])->name('admin.login');
});
Route::middleware(['auth:sanctum, admin', config('jetstream.auth_session'), 'verified'])->group(function () {
Route::get('/admin/dashboard', function () {
return view('dashboard');
})->name('dashboard');
});
Route::middleware(['auth:sanctum, web', config('jetstream.auth_session'), 'verified'])->group(function () {
Route::get('/dashboard', function () {
return view('dashboard');
})->name('dashboard');
});
AdminController
public function loginForm()
{
return view('auth.login', ['guard' => 'admin']);
}
AdminRidirectIfAuthenticated.php
public function handle(Request $request, Closure $next, ...$guards)
{
$guards = empty($guards) ? [null] : $guards;
foreach ($guards as $guard) {
if (Auth::guard($guard)->check()) {
return redirect($guard . '/dashboard');
}
}
return $next($request);
}
LoginResponse.php
public function toResponse($request)
{
return $request->wantsJson()
? response()->json(['two_factor' => false])
: redirect()->intended('admin/dashboard');
}
Kernel.php
protected $routeMiddleware = [
'auth' => \App\Http\Middleware\Authenticate::class,
'auth.basic' => \Illuminate\Auth\Middleware\AuthenticateWithBasicAuth::class,
'auth.session' => \Illuminate\Session\Middleware\AuthenticateSession::class,
'cache.headers' => \Illuminate\Http\Middleware\SetCacheHeaders::class,
'can' => \Illuminate\Auth\Middleware\Authorize::class,
'guest' => \App\Http\Middleware\RedirectIfAuthenticated::class,
'admin' => \App\Http\Middleware\AdminRedirectIfAuthenticated::class,
'password.confirm' => \Illuminate\Auth\Middleware\RequirePassword::class,
'signed' => \Illuminate\Routing\Middleware\ValidateSignature::class,
'throttle' => \Illuminate\Routing\Middleware\ThrottleRequests::class,
'verified' => \Illuminate\Auth\Middleware\EnsureEmailIsVerified::class,
];
FortifyServiceProvider.php
use App\Http\Controllers\AdminController;
use Illuminate\Contracts\Auth\StatefulGuard;
use Illuminate\Support\Facades\Auth;
use App\Actions\Fortify\AttemptToAuthenticate;
use App\Actions\Fortify\RedirectIfTwoFactorAuthenticatable;
public function register()
{
$this->app->when([AdminController::class, AttemptToAuthenticate::class, RedirectIfTwoFactorAuthenticatable::class])
->needs(StatefulGuard::class)
->give(function () {
return Auth::guard('admin');
});
}
login.blade.php
<form method="POST" action="{{ isset($guard) ? url($guard.'/login') : route('login') }}">
#csrf
..............
</form>
AdminStatefulGuard.php
use Illuminate\Contracts\Auth\Authenticatable;
use Illuminate\Contracts\Auth\Guard;
interface AdminStatefulGuard extends Guard
{
/**
* Attempt to authenticate a user using the given credentials.
*
* #param array $credentials
* #param bool $remember
* #return bool
*/
public function attempt(array $credentials = [], $remember = false);
/**
* Log a user into the application without sessions or cookies.
*
* #param array $credentials
* #return bool
*/
public function once(array $credentials = []);
/**
* Log a user into the application.
*
* #param \Illuminate\Contracts\Auth\Authenticatable $user
* #param bool $remember
* #return void
*/
public function login(Authenticatable $user, $remember = false);
/**
* Log the given user ID into the application.
*
* #param mixed $id
* #param bool $remember
* #return \Illuminate\Contracts\Auth\Authenticatable|bool
*/
public function loginUsingId($id, $remember = false);
/**
* Log the given user ID into the application without sessions or cookies.
*
* #param mixed $id
* #return \Illuminate\Contracts\Auth\Authenticatable|bool
*/
public function onceUsingId($id);
/**
* Determine if the user was authenticated via "remember me" cookie.
*
* #return bool
*/
public function viaRemember();
/**
* Log the user out of the application.
*
* #return void
*/
public function logout();
}
Remove space before middleware parameter at web.php
Remove space before admin at 'auth:sanctum, admin'

Error while posting form in laravel (CORS)

I have installed Laravel 7.0 and working with angular 12 as a frontend. I used this package
https://github.com/fruitcake/laravel-cors
This is my kernel.php
<?php
namespace App\Http;
use Illuminate\Foundation\Http\Kernel as HttpKernel;
class Kernel extends HttpKernel
{
/**
* The application's global HTTP middleware stack.
*
* These middleware are run during every request to your application.
*
* #var array
*/
protected $middleware = [
\App\Http\Middleware\TrustProxies::class,
\Fruitcake\Cors\HandleCors::class,
\App\Http\Middleware\CheckForMaintenanceMode::class,
\Illuminate\Foundation\Http\Middleware\ValidatePostSize::class,
\App\Http\Middleware\TrimStrings::class,
\Illuminate\Foundation\Http\Middleware\ConvertEmptyStringsToNull::class,
];
/**
* The application's route middleware groups.
*
* #var array
*/
protected $middlewareGroups = [
'web' => [
\App\Http\Middleware\EncryptCookies::class,
\Illuminate\Cookie\Middleware\AddQueuedCookiesToResponse::class,
\Illuminate\Session\Middleware\StartSession::class,
// \Illuminate\Session\Middleware\AuthenticateSession::class,
\Illuminate\View\Middleware\ShareErrorsFromSession::class,
\App\Http\Middleware\VerifyCsrfToken::class,
\Illuminate\Routing\Middleware\SubstituteBindings::class,
],
'api' => [
'throttle:60,1',
\Illuminate\Routing\Middleware\SubstituteBindings::class,
],
];
/**
* The application's route middleware.
*
* These middleware may be assigned to groups or used individually.
*
* #var array
*/
protected $routeMiddleware = [
'auth' => \App\Http\Middleware\Authenticate::class,
'auth.basic' => \Illuminate\Auth\Middleware\AuthenticateWithBasicAuth::class,
'bindings' => \Illuminate\Routing\Middleware\SubstituteBindings::class,
'cache.headers' => \Illuminate\Http\Middleware\SetCacheHeaders::class,
'can' => \Illuminate\Auth\Middleware\Authorize::class,
'guest' => \App\Http\Middleware\RedirectIfAuthenticated::class,
'password.confirm' => \Illuminate\Auth\Middleware\RequirePassword::class,
'signed' => \Illuminate\Routing\Middleware\ValidateSignature::class,
'throttle' => \Illuminate\Routing\Middleware\ThrottleRequests::class,
'verified' => \Illuminate\Auth\Middleware\EnsureEmailIsVerified::class,
];
}
cors.php
<?php
return [
/*
|--------------------------------------------------------------------------
| Cross-Origin Resource Sharing (CORS) Configuration
|--------------------------------------------------------------------------
|
| Here you may configure your settings for cross-origin resource sharing
| or "CORS". This determines what cross-origin operations may execute
| in web browsers. You are free to adjust these settings as needed.
|
| To learn more: https://developer.mozilla.org/en-US/docs/Web/HTTP/CORS
|
*/
'paths' => ['api/*'],
'allowed_methods' => ['*'],
'allowed_origins' => ['*'],
'allowed_origins_patterns' => [],
'allowed_headers' => ['*'],
'exposed_headers' => ['*'],
'max_age' => 0,
'supports_credentials' => true,
];
api.php
Route::group(['middleware' => ['api']], function ($router) {
Route::post('/contact-us', [SiteController::class, 'contactUs']);
});
Route::group([
'middleware' => ['api'],
'prefix' => 'auth'
], function ($router) {
Route::post('/login', [AuthController::class, 'login']);
Route::get('/user-profile', [AuthController::class, 'Profile']);
});
I'm getting this error :
Access to XMLHttpRequest at 'http://127.0.0.1:8000/api/auth/login'
from origin 'http://localhost:4200' has been blocked by CORS policy:
No 'Access-Control-Allow-Origin' header is present on the requested
resource.
Testing with own CORS middleware
No 'Access-Control-Allow-Origin' header is present on the requested resource.
The website handling the request (here localhost:4200) must set this header to allow requests cross-origin. So the package doesn't do anything, apparently.
I cannot help with the package used, but here is how to set the headers with your own middleware (may help others). Change the headers as you see fit. We'll use this for testing:
app/Http/Middleware/Cors.php
<?php
namespace App\Http\Middleware;
use Closure;
class Cors
{
/**
* Handle an incoming request.
*
* #param \Illuminate\Http\Request $request
* #param \Closure $next
* #return mixed
*/
public function handle($request, Closure $next)
{
return $next($request)
->header('Access-Control-Allow-Origin', '*')
->header('Access-Control-Allow-Headers', 'Authorization')
->header('Access-Control-Allow-Methods', 'POST, GET, PUT, DELETE, PATCH');
}
}
In app/Http/Kernel.php we add it to $middleware:
protected $middleware = [
// ...
\App\Http\Middleware\Cors::class,
];
The server should now set the respective headers.
This might not be your solution, but you can at least debug what is different.
Documentation for Access-Control-Allow-...:
https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Access-Control-Allow-Headers

How to restrict access to routes at certain times in laravel

I was wondering if there is a way to restrict access to routes-blades at certain hours or minutes within a day ?
Any documentation about this topic ?
Create a middleware
php artisan make:middleware TimeBasedRestriction
Return a different response or redirect if time isn't appropriate
<?php
namespace App\Http\Middleware;
use Closure;
class TimeBasedRestriction
{
/**
* Handle an incoming request.
*
* #param \Illuminate\Http\Request $request
* #param \Closure $next
* #return mixed
*/
public function handle($request, Closure $next)
{
// if not working hours, access forbidden
if (!now()->isBetween('09:00:00', '16:00:00')) {
return response()->json([
'message' => 'Day is over, come back tomorrow'
], 403); // Status forbidden
}
return $next($request);
}
}
Add the middleware to your route middleware in app\Http\Kernel.php
protected $routeMiddleware = [
'auth' => \App\Http\Middleware\Authenticate::class,
'auth.basic' => \Illuminate\Auth\Middleware\AuthenticateWithBasicAuth::class,
'bindings' => \Illuminate\Routing\Middleware\SubstituteBindings::class,
'cache.headers' => \Illuminate\Http\Middleware\SetCacheHeaders::class,
'can' => \Illuminate\Auth\Middleware\Authorize::class,
'guest' => \App\Http\Middleware\RedirectIfAuthenticated::class,
'signed' => \Illuminate\Routing\Middleware\ValidateSignature::class,
'throttle' => \Illuminate\Routing\Middleware\ThrottleRequests::class,
'verified' => \Illuminate\Auth\Middleware\EnsureEmailIsVerified::class,
'restrictedToDayLight' => \App\Http\Middleware\TimeBasedRestriction::class,
];
And add it to your restricted routes in web.php for example
Route::get('/', function () {
return view('welcome');
})->middleware('restrictedToDayLight');

Laravel 5.8: Multi users authentication issue

in my laravel project, I have two users (Admins and Users).
I got started admins' authentification.
Now when I go to a create page (http://127.0.0.1:8000/admin/posts/create) in my CRUD application, it redirects to http://127.0.0.1:8000/login.
I am glad if someone gives me a solution to go back to http://127.0.0.1:8000/admin/login page which is admin side login page.
Here is my codes.
web.php
Route::prefix('admin')->group(function(){
Route::get('/login', 'Auth\AdminLoginController#showLoginForm')->name('admin.login');
Route::post('/login', 'Auth\AdminLoginController#login')->name('admin.login.submit');
Route::get('/', 'AdminController#index')->name('admin.dashboard');
Route::resource('categories','CategoriesController');
Route::resource('posts', 'PostsController')->middleware('auth');
Route::get('trashed-posts', 'PostsController#trashed')->name('trashed-posts.index');
Route::PUT('restore-post/{post}', 'PostsController#restore')->name('restore-posts');
});
VerifyCategoriesCount.php in my middleware folder
public function handle($request, Closure $next)
{
if (Auth::check()) {
if (Auth::user()->role == 'Admin') {
return $next($request);
}
}
return redirect('/admin/');
}
kernel.php
protected $routeMiddleware = [
'auth' => \App\Http\Middleware\Authenticate::class,
'auth.basic' => \Illuminate\Auth\Middleware\AuthenticateWithBasicAuth::class,
'bindings' => \Illuminate\Routing\Middleware\SubstituteBindings::class,
'cache.headers' => \Illuminate\Http\Middleware\SetCacheHeaders::class,
'can' => \Illuminate\Auth\Middleware\Authorize::class,
'guest' => \App\Http\Middleware\RedirectIfAuthenticated::class,
'signed' => \Illuminate\Routing\Middleware\ValidateSignature::class,
'throttle' => \Illuminate\Routing\Middleware\ThrottleRequests::class,
'verified' => \Illuminate\Auth\Middleware\EnsureEmailIsVerified::class,
'verifyCategoriesCount' => VerifyCategoriesCount::class
];
postsController.php
public function __construct()
{
$this->middleware('VerifyCategoriesCount')->only('store');
$this->middleware('admin')->except('index');
}
Add an admin guard in auth.php
'admin' => [
'driver' => 'session',
'provider' => 'admins', //table name
],
And add providers array
'admins' => [
'driver' => 'eloquent',
'model' => App\Admin::class, //Bind your Admin Model
],
Add two middleware,
class AdminRedirectIfAuthenticated
{
/**
* Handle an incoming request.
*
* #param \Illuminate\Http\Request $request
* #param \Closure $next
* #return mixed
*/
public function handle($request, Closure $next)
{
if (Auth::guard('admin')->check()) {
return redirect('/admin/home');
}
return $next($request);
}
}
And
class AdminRedirectIfNotAuthenticated
{
/**
* Handle an incoming request.
*
* #param \Illuminate\Http\Request $request
* #param \Closure $next
* #return mixed
*/
public function handle($request, Closure $next)
{
if (!Auth::guard('admin')->check()) {
return redirect('/admin/login');
}
return $next($request);
}
}
Register your middlewares in kernel.php
'admin.auth' => \App\Http\Middleware\AdminRedirectIfNotAuthenticated::class,
'admin.guest' => \App\Http\Middleware\AdminRedirectIfAuthenticated::class,
In your AdminController.php add,
public function __construct()
{
$this->middleware('admin.auth');
}
And,
In your LoginController.php add,
public function __construct()
{
$this->middleware('admin.guest');
}
In web.php
Route::get('/admin/login', 'Admin\LoginController#showLoginForm')->name('admin.login');
Route::get('/admin/home', 'Admin\AdminController#home')->name('home');

Auth::check() is always false in middleware in Laravel 5.7

I have used middlewares for many Laravel applications, but this is a stupid situation never happened to me before. The middleware always returns false for Auth::check()
This is routes of User module
<?php
Route::group(['middleware' => 'web', 'namespace' => 'Modules\User\Http\Controllers'], function () {
Route::get('/', 'UserController#index');
Route::get('login', 'LoginController#showLoginForm')->name('login');
Route::post('login', 'LoginController#login');
Route::post('logout', 'LoginController#logout')->name('logout');
});
Route::group(['middleware' => 'admin', 'prefix' => 'user', 'namespace' => 'Modules\User\Http\Controllers'], function () {
Route::get('register', 'RegisterController#showRegistrationForm')->name('register');
Route::post('register', 'RegisterController#register');
});
This is AdminMiddleware inside the User module
<?php
namespace Modules\User\Http\Middleware;
use Closure;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;
class AdminMiddleware
{
/**
* Handle an incoming request.
*
* #param \Illuminate\Http\Request $request
* #param \Closure $next
* #return mixed
*/
public function handle(Request $request, Closure $next)
{
$log = Auth::check();
dd($log);
return $next($request);
}
}
and this is kernel.php
protected $routeMiddleware = [
'auth' => \App\Http\Middleware\Authenticate::class,
'auth.basic' => \Illuminate\Auth\Middleware\AuthenticateWithBasicAuth::class,
'bindings' => \Illuminate\Routing\Middleware\SubstituteBindings::class,
'cache.headers' => \Illuminate\Http\Middleware\SetCacheHeaders::class,
'can' => \Illuminate\Auth\Middleware\Authorize::class,
'guest' => \App\Http\Middleware\RedirectIfAuthenticated::class,
'signed' => \Illuminate\Routing\Middleware\ValidateSignature::class,
'throttle' => \Illuminate\Routing\Middleware\ThrottleRequests::class,
'verified' => \Illuminate\Auth\Middleware\EnsureEmailIsVerified::class,
'admin' => \Modules\User\Http\Middleware\AdminMiddleware::class
];
But the result of dd($log) is always false. What is wrong here?!!!
You also need to add web middleware to User module routes group.
Because the session starts there.
Just saying, another solution is that you added it to the global middleware stack instead of the web middleware group! (Only add it to web, it can't be both)
please append your middleware address:
\Modules\User\Http\Middleware\AdminMiddleware::class
to
protected $middlewareGroups = [
'web' => [
\App\Http\Middleware\EncryptCookies::class,
\Illuminate\Cookie\Middleware\AddQueuedCookiesToResponse::class,
\Illuminate\Session\Middleware\StartSession::class,
// \Illuminate\Session\Middleware\AuthenticateSession::class,
\Illuminate\View\Middleware\ShareErrorsFromSession::class,
\App\Http\Middleware\VerifyCsrfToken::class,
\Illuminate\Routing\Middleware\SubstituteBindings::class,
\Modules\User\Http\Middleware\AdminMiddleware::class //this is your middleware.
],
'api' => [
'throttle:60,1',
\Illuminate\Routing\Middleware\SubstituteBindings::class,
],
];
you can set your middleware's priority to be loaded after StartSession to be sure it will be loaded after the session starts.
in kernel.php
protected $middlewarePriority = [
\Illuminate\Session\Middleware\StartSession::class,
\Illuminate\View\Middleware\ShareErrorsFromSession::class,
\Modules\User\Http\Middleware\AdminMiddleware::class
\App\Http\Middleware\Authenticate::class,
\Illuminate\Routing\Middleware\ThrottleRequests::class,
\Illuminate\Session\Middleware\AuthenticateSession::class,
\Illuminate\Routing\Middleware\SubstituteBindings::class,
\Illuminate\Auth\Middleware\Authorize::class,
\App\Http\Middleware\CheckProfileRequiredData::class, // putting CheckProfileRequiredData after Auth priority is required! to perform it's check after auth middleware
\App\Http\Middleware\CheckUserMustPayWithoutAnsweringDietRequiredQuestions::class,
];

Resources