The error says that the admin.login route doesn't exist. So show us your route definitions.
Route [admin.login] not defined.
I just upgraded from laravel 8 into laravel 9
Then this route error showed up
This error was not appeared in laravel 8
the source of the error is in this file /app/Http/Middleware/AuthAdmin.php
<?php
namespace App\Http\Middleware;
use Closure;
use Illuminate\Auth\AuthenticationException;
use Illuminate\Contracts\Auth\Factory as Auth;
class AuthAdmin
{
/**
* The authentication factory instance.
*
* @var \Illuminate\Contracts\Auth\Factory
*/
protected $auth;
/**
* Create a new middleware instance.
*
* @return void
*/
public function __construct(Auth $auth)
{
$this->auth = $auth;
}
/**
* Handle an incoming request.
*
* @param \Illuminate\Http\Request $request
* @return mixed
*
* @throws \Illuminate\Auth\AuthenticationException
*/
public function handle($request, Closure $next)
{
$this->authenticate($request, ['admin']);
return $next($request);
}
/**
* Determine if the user is logged in to any of the given guards.
*
* @param \Illuminate\Http\Request $request
* @return void
*
* @throws \Illuminate\Auth\AuthenticationException
*/
protected function authenticate($request, array $guards)
{
if (empty($guards)) {
$guards = [null];
}
foreach ($guards as $guard) {
if ($this->auth->guard($guard)->check()) {
return $this->auth->shouldUse($guard);
}
}
throw new AuthenticationException(
'Unauthenticated.', $guards, $this->redirectTo($request)
);
}
/**
* Get the path the user should be redirected to when they are not authenticated.
*
* @param \Illuminate\Http\Request $request
* @return string
*/
protected function redirectTo($request)
{
if (! $request->expectsJson()) {
return route('admin.login');
}
}
}
this is my current route
<?php
use App\Http\Controllers\Admin\AdminUserController;
use App\Http\Controllers\Admin\Agent;
use App\Http\Controllers\Admin\ApplicationController;
use App\Http\Controllers\Admin\Auth;
use App\Http\Controllers\Admin\CheckController;
use App\Http\Controllers\Admin\Developer;
use App\Http\Controllers\Admin\EditApplicationController;
use App\Http\Controllers\Admin\HomeController;
use App\Http\Controllers\Admin\KaveatBuyerController;
use App\Http\Controllers\Admin\KaveatController;
use App\Http\Controllers\Admin\KaveatHakmilikController;
use App\Http\Controllers\Admin\ManualApplicationController;
use App\Http\Controllers\Admin\MoratoriumController;
use App\Http\Controllers\Admin\OfferController;
use App\Http\Controllers\Admin\PaymentController2;
use App\Http\Controllers\Admin\ProfileController;
use App\Http\Controllers\Admin\Project;
use App\Http\Controllers\Admin\ReportController;
use App\Http\Controllers\Admin\ReviewController;
use App\Http\Controllers\Admin\SchemeController;
use App\Http\Controllers\Admin\SettingController;
use App\Http\Controllers\Admin\SuperController;
use Illuminate\Support\Facades\Route;
\Auth::routes(['register' => false]);
Route::middleware(['auth.admin', 'set_locale'])->group(function () {
Route::get('/download-template/lotunit', [HomeController::class, 'downloadTemplateLotUnit']);
Route::get('/logout', [Auth\LoginController::class, 'logout'])->name('logout');
Route::get('/info', [HomeController::class, 'info'])->name('info');
Route::get('/info-delete/{filename}', [HomeController::class, 'infoDelete'])->name('info-delete');
Route::post('/info', [HomeController::class, 'uploadInfo'])->name('info');
Route::get('/home/{scheme?}', [HomeController::class, 'home'])->name('home');
Route::get('/profile/rent', [ProfileController::class, 'manageRent'])->name('profile.rent');
Route::get('/profile/rent-detail/{ic}', [ProfileController::class, 'rentDetail'])->name('profile.rent-detail');
For laravel 8 I put my route for authentication inside /vendor/laravel/ui/src/RouteAuthMethods.php
<?php
namespace Laravel\Ui;
class AuthRouteMethods
{
/**
* Register the typical authentication routes for an application.
*
* @param array $options
* @return callable
*/
public function auth()
{
return function ($options = []) {
$namespace = class_exists($this->prependGroupNamespace('Auth\LoginController')) ? null : 'App\Http\Controllers';
$this->group(['namespace' => $namespace], function() use($options) {
// Login Routes...
if ($options['admin_login'] ?? true) {
$this->get('admin/login', 'Admin\Auth\LoginController@showLoginForm')->name('admin.login');
$this->post('admin/login', 'Admin\Auth\LoginController@login');
}
if ($options['user_login'] ?? true) {
$this->get('user/login', 'User\Auth\LoginController@showLoginForm')->name('user.login');
$this->post('user/login', 'User\Auth\LoginController@login');
}
if ($options['developer_login'] ?? true) {
$this->get('developer/login', 'Developer\Auth\LoginController@showLoginForm')->name('developer.login');
$this->post('developer/login', 'Developer\Auth\LoginController@login');
}
if ($options['agent_login'] ?? true) {
$this->get('agent/login', 'Developer\Auth\LoginController@showLoginForm')->name('agent.login');
$this->post('agent/login', 'Developer\Auth\LoginController@login');
}
if ($options['moratorium_login'] ?? true) {
$this->get('moratorium/login', 'Developer\Auth\LoginController@showLoginForm')->name('moratorium.login');
$this->post('moratorium/login', 'Developer\Auth\LoginController@login');
}
i just realized that this error also appeared in my blade file
<a class="nav-link text-nowrap {{ request()->segment(1) == 'admin'? 'active' : '' }}" href="{{ route('admin.login') }}">{{ __('URUS SETIA') }}</a>
</li>
@safwan5605 Do not edit/customize package files directly. For instance, after updating Laravel from version 8 to 9, Laravel UI was also updated, which may have resulted in the loss of your customizations in /vendor/laravel/ui/src/RouteAuthMethods.php. To prevent this, define your authentication routes in the web.php file.
There is no change in my customization after updating from 8 to 9
But if I removed those customization, the error is gone but my authentication for my website does not working anymore
In laravel 8, those customization makes my authentication worked properly
@safwan5605 you are learning the hard way never to edit anything inside vendor folder
You will have to redo these customisations, but this time, not in vendor.
Like the others said never directly edit the vendor folder (or node_modules for front-end) Those are folders created by the package managers.
Composer in this case.
Lets say you downloaded the Laravel debugbar by running composer require barryvdh/laravel-debugbar --dev
It creates a folder within your vendor folder with the code to run that package.
If you then change a file and after a whole you decide to run composer update you have the risk of losing those changes.
Git also do not track the changes within the vendor folder.
If you want to adjust code of a certain package you have to find ways to for example extend that piece of code. So browsing the docs for that package is a way to find what you are looking for.
You do have to make these changes yourself again in your own app, so not in the vendor folder.
Simply add the routes you want to the routes/web.php file.
Routing documentation can be found here. https://laravel.com/docs/11.x/routing#main-content
What you probably want to add is something like this
$this->get('admin/login', 'Admin\Auth\LoginController@showLoginForm')->name('admin.login');
$this->post('admin/login', 'Admin\Auth\LoginController@login');
@safwan5605 Well have you defined a route named admin.login?
this is my current route
use App\Http\Controllers\Admin\Auth;
\Auth::routes(['register' => false]);
Route::middleware(['auth.admin', 'set_locale'])->group(function () {
Route::get('/download-template/lotunit', [HomeController::class, 'downloadTemplateLotUnit']);
Route::get('/logout', [Auth\LoginController::class, 'logout'])->name('logout');
Route::get('/admin/login', [Auth\LoginController::class, 'showLoginForm'])->name('admin.login');
@safwan5605 Do you see the route when you run php artisan route:list?
That's the weird part actually
I'm only saw Auth/LoginController@showLoginForm for admin/login
It should be Admin/Auth/LoginController@showLoginForm
I already made a few adjustments but nothing works
@safwan5605 Your old routes may be cached, or you may be redefining the /admin/login route somewhere and the admin.login in your route file gets overwritten. I suggest you do the following steps:
- Check that there's no other
/admin/loginGET route anywhere in your route files. - Run
php artisan route:clear, thenphp artisan route:listagain to see if the new route appears. The first command clears cached routes. You should only cache routes in production, not during development. - Earlier you mentioned making changes to vendor files, which you should never do. Delete the vendor directory and reinstall the packages using
composer install.
-
I already double checked and there is no other /admin/login
-
I already did that and this is what i got from route:list
GET|HEAD admin/login .................................................................................. admin.login › Auth\LoginController@showLoginForm
POST admin/login ............................................................................................... admin. › Auth\LoginController@login
POST admin/logout ....................................................................................... admin.logout › Auth\LoginController@logout
GET|HEAD admin/logout ................................................................................. admin.logout › Admin\Auth\LoginController@logout
Still not a correct route for admin.login while logout has a correct route
I already installed the new vendor directory
Whatever i made change in my LoginController
my login always redirect from vendor/laravel/ui/auth-backend/AuthenticateUsers.php
Looks like my LoginController has been ignored by my code
This is my current AuthenticateUsers.php
<?php
namespace Illuminate\Foundation\Auth;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;
use Illuminate\Validation\ValidationException;
trait AuthenticatesUsers
{
use RedirectsUsers, ThrottlesLogins;
/**
* Show the application's login form.
*
* @return \Illuminate\View\View
*/
public function showLoginForm()
{
return view('auth.login');
}
/**
* Handle a login request to the application.
*
* @param \Illuminate\Http\Request $request
* @return \Illuminate\Http\RedirectResponse|\Illuminate\Http\Response|\Illuminate\Http\JsonResponse
*
* @throws \Illuminate\Validation\ValidationException
*/
public function login(Request $request)
{
$this->validateLogin($request);
// If the class is using the ThrottlesLogins trait, we can automatically throttle
// the login attempts for this application. We'll key this by the username and
// the IP address of the client making these requests into this application.
if (method_exists($this, 'hasTooManyLoginAttempts') &&
$this->hasTooManyLoginAttempts($request)) {
$this->fireLockoutEvent($request);
return $this->sendLockoutResponse($request);
}
if ($this->attemptLogin($request)) {
if ($request->hasSession()) {
$request->session()->put('auth.password_confirmed_at', time());
}
return $this->sendLoginResponse($request);
}
// If the login attempt was unsuccessful we will increment the number of attempts
// to login and redirect the user back to the login form. Of course, when this
// user surpasses their maximum number of attempts they will get locked out.
$this->incrementLoginAttempts($request);
return $this->sendFailedLoginResponse($request);
}
/**
* Validate the user login request.
*
* @param \Illuminate\Http\Request $request
* @return void
*
* @throws \Illuminate\Validation\ValidationException
*/
protected function validateLogin(Request $request)
{
$request->validate([
$this->username() => 'required|string',
'password' => 'required|string',
]);
}
/**
* Attempt to log the user into the application.
*
* @param \Illuminate\Http\Request $request
* @return bool
*/
protected function attemptLogin(Request $request)
{
return $this->guard()->attempt(
$this->credentials($request), $request->boolean('remember')
);
}
/**
* Get the needed authorization credentials from the request.
*
* @param \Illuminate\Http\Request $request
* @return array
*/
protected function credentials(Request $request)
{
return $request->only($this->username(), 'password');
}
/**
* Send the response after the user was authenticated.
*
* @param \Illuminate\Http\Request $request
* @return \Illuminate\Http\RedirectResponse|\Illuminate\Http\JsonResponse
*/
protected function sendLoginResponse(Request $request)
{
$request->session()->regenerate();
$this->clearLoginAttempts($request);
if ($response = $this->authenticated($request, $this->guard()->user())) {
return $response;
}
return $request->wantsJson()
? new JsonResponse([], 204)
: redirect()->intended($this->redirectPath());
}
/**
* The user has been authenticated.
*
* @param \Illuminate\Http\Request $request
* @param mixed $user
* @return mixed
*/
protected function authenticated(Request $request, $user)
{
//
}
/**
* Get the failed login response instance.
*
* @param \Illuminate\Http\Request $request
* @return \Symfony\Component\HttpFoundation\Response
*
* @throws \Illuminate\Validation\ValidationException
*/
protected function sendFailedLoginResponse(Request $request)
{
throw ValidationException::withMessages([
$this->username() => [trans('auth.failed')],
]);
}
/**
* Get the login username to be used by the controller.
*
* @return string
*/
public function username()
{
return 'email';
}
/**
* Log the user out of the application.
*
* @param \Illuminate\Http\Request $request
* @return \Illuminate\Http\RedirectResponse|\Illuminate\Http\JsonResponse
*/
public function logout(Request $request)
{
$this->guard()->logout();
$request->session()->invalidate();
$request->session()->regenerateToken();
if ($response = $this->loggedOut($request)) {
return $response;
}
return $request->wantsJson()
? new JsonResponse([], 204)
: redirect('/');
}
/**
* The user has logged out of the application.
*
* @param \Illuminate\Http\Request $request
* @return mixed
*/
protected function loggedOut(Request $request)
{
//
}
/**
* Get the guard to be used during authentication.
*
* @return \Illuminate\Contracts\Auth\StatefulGuard
*/
protected function guard()
{
return Auth::guard();
}
}
@safwan5605 Your admin.login route shows a POST route, not GET route. And it doesn't show any of the routes that would be registered by \Auth::routes(['register' => false]);.
If that's the entire output of route:list, then the routes you listed aren't registered at all. Is that snippet from routes/web.php?
It still doesn't explain where the POST route for admin.login comes from. It has to be registered somewhere (if your old routes aren't cached).
Those are the only route that related to login and logout of the admin
which snippet ?
@safwan5605 This one:
use App\Http\Controllers\Admin\Auth;
\Auth::routes(['register' => false]);
Route::middleware(['auth.admin', 'set_locale'])->group(function () {
Route::get('/download-template/lotunit', [HomeController::class, 'downloadTemplateLotUnit']);
Route::get('/logout', [Auth\LoginController::class, 'logout'])->name('logout');
Route::get('/admin/login', [Auth\LoginController::class, 'showLoginForm'])->name('admin.login');
Where is this code located? Is it in routes/web.php?
Yes, to be precise I specified the route for different users such as web-admin, web-agent,web-user
So basically that snippet is from web-admin.php where it contained all route that related to the admin
@safwan5605 And how are you registering the routes in web-admin.php? Are you including the file in web.php, or have you modified the route service provider?
By default, only the routes defined in web.php and api.php are registered by the route service provider.
Yes correct, I modified route service provider like this
protected function mapWebRoutes()
{
Route::middleware('web')
->group(base_path('routes/web.php'));
Route::middleware('web')
->name('admin.')
->prefix('admin')
->group(base_path('routes/web-admin.php'));
Route::middleware('web')
->name('agent.')
->prefix('agent')
->group(base_path('routes/web-agent.php'));
Route::middleware('web')
->name('user.')
->prefix('user')
->group(base_path('routes/web-user.php'));
@safwan5605 Those are not going to work with the route definitions you posted earlier. Run php artisan route:list to list the routes and you'll see what I mean. You defined a name and a prefix for the web-admin group in your provider, but you've defined full paths and names for the routes in web-admin.php. The result will be route names such as admin.admin.login and paths like admin/admin/login.
Should I remove the prefix and name in the service provider ?
Based on your reply, now I tried to make something like this
Route::get('/logout', [Auth\LoginController::class, 'logout'])->name('logout');
Route::get('/login', [Auth\LoginController::class, 'showLoginForm'])->name('login');
and this is the php artisan route:list
GET|HEAD admin/login ............................................................................ admin.login › Admin\Auth\LoginController@showLoginForm
GET|HEAD admin/logout ................................................................................. admin.logout › Admin\Auth\LoginController@logout
But I got this error ERR_TOO_MANY_REDIRECTS
@safwan5605 The route is good now.
The latest error you're getting is because there's an infinite redirection loop somewhere. It's a separate issue. Walk the path of your request through middlewares and controllers to see what's causing it.
Can I know which middleware cause that problem ?
because currently I have this middleware for AuthAdmin.php
<?php
namespace App\Http\Middleware;
use Closure;
use Illuminate\Auth\AuthenticationException;
use Illuminate\Contracts\Auth\Factory as Auth;
use Illuminate\Http\Request;
use Symfony\Component\HttpFoundation\Response;
class AuthAdmin
{
/**
* The authentication factory instance.
*
* @var \Illuminate\Contracts\Auth\Factory
*/
protected $auth;
/**
* Create a new middleware instance.
*
* @return void
*/
public function __construct(Auth $auth)
{
$this->auth = $auth;
}
/**
* Handle an incoming request.
*
*
* @throws \Illuminate\Auth\AuthenticationException
*/
public function handle(Request $request, Closure $next): Response
{
$this->authenticate($request, ['admin']);
return $next($request);
}
/**
* Determine if the user is logged in to any of the given guards.
*
*
* @throws \Illuminate\Auth\AuthenticationException
*/
protected function authenticate(Request $request, array $guards): void
{
if (empty($guards)) {
$guards = [null];
}
/* foreach ($guards as $guard) {
if ($this->auth->guard($guard)->check()) {
return $this->auth->shouldUse($guard);
}
}*/
foreach ($guards as $guard) {
if ($this->auth->guard($guard)->check()) {
$this->auth->shouldUse($guard);
// handle the return value of shouldUse() if needed
// return or assign it to a variable
return; // or return something else if needed
}
}
throw new AuthenticationException(
'Unauthenticated.', $guards, $this->redirectTo($request)
);
}
/**
* Get the path the user should be redirected to when they are not authenticated.
*/
protected function redirectTo(Request $request): string
{
if (! $request->expectsJson()) {
return route('admin.login');
}
}
}
@safwan5605 Did you at least try to debug it yourself? If you're adding your own custom guards and authorization middleware, you should understand the code.
Anyway, the original problem was resolved and this is already a different topic.
This site has videos about authorization and authentication. They might be worth checking out.
Ok I understand, Thank you for your guidance
Ok guys, thank you for the advice, I will try to edit my web.php first and see what will happen
Hi, I already removed all the edit I made inside vendor
I wonder why does my auth redirect to inside laravel/ui eventhough I have my own LoginController inside my directory /app/Http/Controllers/Admin/Auth/LoginController.php
this is my inside larave/ui/auth-backend/AuthenticateUsers.php
namespace Illuminate\Foundation\Auth;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;
use Illuminate\Validation\ValidationException;
trait AuthenticatesUsers
{
use RedirectsUsers, ThrottlesLogins;
/**
* Show the application's login form.
*
* @return \Illuminate\View\View
*/
public function showLoginForm()
{
return view('auth.login');
}
/**
* Handle a login request to the application.
*
* @param \Illuminate\Http\Request $request
* @return \Illuminate\Http\RedirectResponse|\Illuminate\Http\Response|\Illuminate\Http\JsonResponse
*
* @throws \Illuminate\Validation\ValidationException
*/
public function login(Request $request)
{
$this->validateLogin($request);
// If the class is using the ThrottlesLogins trait, we can automatically throttle
// the login attempts for this application. We'll key this by the username and
// the IP address of the client making these requests into this application.
if (method_exists($this, 'hasTooManyLoginAttempts') &&
$this->hasTooManyLoginAttempts($request)) {
$this->fireLockoutEvent($request);
return $this->sendLockoutResponse($request);
}
if ($this->attemptLogin($request)) {
if ($request->hasSession()) {
$request->session()->put('auth.password_confirmed_at', time());
}
return $this->sendLoginResponse($request);
}
// If the login attempt was unsuccessful we will increment the number of attempts
// to login and redirect the user back to the login form. Of course, when this
// user surpasses their maximum number of attempts they will get locked out.
$this->incrementLoginAttempts($request);
return $this->sendFailedLoginResponse($request);
}
/**
* Validate the user login request.
*
* @param \Illuminate\Http\Request $request
* @return void
*
* @throws \Illuminate\Validation\ValidationException
*/
protected function validateLogin(Request $request)
{
$request->validate([
$this->username() => 'required|string',
'password' => 'required|string',
]);
}
/**
* Attempt to log the user into the application.
*
* @param \Illuminate\Http\Request $request
* @return bool
*/
protected function attemptLogin(Request $request)
{
return $this->guard()->attempt(
$this->credentials($request), $request->boolean('remember')
);
}
/**
* Get the needed authorization credentials from the request.
*
* @param \Illuminate\Http\Request $request
* @return array
*/
protected function credentials(Request $request)
{
return $request->only($this->username(), 'password');
}
/**
* Send the response after the user was authenticated.
*
* @param \Illuminate\Http\Request $request
* @return \Illuminate\Http\RedirectResponse|\Illuminate\Http\JsonResponse
*/
protected function sendLoginResponse(Request $request)
{
$request->session()->regenerate();
$this->clearLoginAttempts($request);
if ($response = $this->authenticated($request, $this->guard()->user())) {
return $response;
}
return $request->wantsJson()
? new JsonResponse([], 204)
: redirect()->intended($this->redirectPath());
}
/**
* The user has been authenticated.
*
* @param \Illuminate\Http\Request $request
* @param mixed $user
* @return mixed
*/
protected function authenticated(Request $request, $user)
{
//
}
/**
* Get the failed login response instance.
*
* @param \Illuminate\Http\Request $request
* @return \Symfony\Component\HttpFoundation\Response
*
* @throws \Illuminate\Validation\ValidationException
*/
protected function sendFailedLoginResponse(Request $request)
{
throw ValidationException::withMessages([
$this->username() => [trans('auth.failed')],
]);
}
/**
* Get the login username to be used by the controller.
*
* @return string
*/
public function username()
{
return 'email';
}
/**
* Log the user out of the application.
*
* @param \Illuminate\Http\Request $request
* @return \Illuminate\Http\RedirectResponse|\Illuminate\Http\JsonResponse
*/
public function logout(Request $request)
{
$this->guard()->logout();
$request->session()->invalidate();
$request->session()->regenerateToken();
if ($response = $this->loggedOut($request)) {
return $response;
}
return $request->wantsJson()
? new JsonResponse([], 204)
: redirect('/');
}
/**
* The user has logged out of the application.
*
* @param \Illuminate\Http\Request $request
* @return mixed
*/
protected function loggedOut(Request $request)
{
//
}
/**
* Get the guard to be used during authentication.
*
* @return \Illuminate\Contracts\Auth\StatefulGuard
*/
protected function guard()
{
return Auth::guard();
}
}
This is my current admin LoginController
<?php
namespace App\Http\Controllers\Admin\Auth;
use App\Http\Controllers\Controller;
use Carbon\Carbon;
use Illuminate\Contracts\Auth\StatefulGuard;
use Illuminate\Foundation\Auth\AuthenticatesUsers;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;
use Illuminate\View\View;
class LoginController extends Controller
{
/*
|--------------------------------------------------------------------------
| Login Controller
|--------------------------------------------------------------------------
|
| This controller handles authenticating users for the application and
| redirecting them to your home screen. The controller uses a trait
| to conveniently provide its functionality to your applications.
|
*/
use AuthenticatesUsers;
/**
* Where to redirect users after login.
*
* @var string
*/
protected $redirectTo = '/admin/home';
/**
* Create a new controller instance.
*
* @return void
*/
public function __construct()
{
$this->middleware('guest:admin')->except('logout');
}
/**
* Show the application's login form.
*/
public function showLoginForm(): View
{
return view('admin.auth.login');
}
/**
* Get the guard to be used during authentication.
*/
protected function guard(): StatefulGuard
{
return Auth::guard('admin');
}
public function authenticated(Request $request, $user)
{
$user->update([
'last_login_at' => Carbon::now()->toDateTimeString(),
]);
}
}
@safwan5605 Why are you using the Illuminate\Foundation\Auth namespace in your own code?
Anyways, the original problem was that your admin.login route wasn't registered. It shouldn't be a hard fix. Any vendor code is irrelevant.
Im using it when it is still laravel 5, now I upgraded to laravel 10, I dont know what to change in that controller
Please or to participate in this conversation.