Laravel 5.5提交登录表单触发MethodNotAllowedHttpException错误求助
Hey there, let's break down the MethodNotAllowedHttpException you're hitting when submitting the login form. This error almost always means your form is using an HTTP method (like POST) that doesn't have a matching route defined. Let's walk through the fixes step by step:
1. Missing POST Route for Login Submission
Your login form uses method="post" to submit credentials, but your routes only define a GET route for /login (which loads the form). There's no route handling the POST request, which is the root cause of the error.
Fix: Add the POST Login Route
Update your routes file to include a POST route pointing to your postLogin method:
Route::get('/', ['as' => '/', 'uses' => 'LoginController@getLogin']); Route::get('/login', ['as' => 'login', 'uses' => 'LoginController@getLogin']); // Add this POST route for form submission Route::post('/login', ['as' => 'login.submit', 'uses' => 'LoginController@postLogin']); // Fix typo: "autheticates" → "authenticates" (missing an 'n') Route::group(['middleware' => ['authenticates', 'roles']], function (){ Route::get('/logout', ['as' => 'logout', 'uses' => 'LoginController@getLogout']); Route::get('/dashboard', ['as' => 'dashboard', 'uses' => 'DashboardController@dashboard']); });
Then update your form's action to use this new POST route:
<form class="login-form" action="{{ route('login.submit') }}" method="post">
2. Typo in Middleware Name
You have a typo in your route group middleware: autheticates should be authenticates (missing an 'n'). This would cause Laravel to fail loading the middleware, leading to unexpected behavior even after fixing the route issue.
Also, make sure your middleware class name matches the corrected name: rename Autheticates.php to Authenticates.php and fix the class definition inside:
class Authenticates { public function handle($request, Closure $next, $guard = 'web') { if (!Auth::guard($guard)->check()) { return redirect()->route('/'); } return $next($request); } }
3. Broken Logic in Roles Middleware
Your Roles middleware has a logical error that would let users bypass role checks entirely:
// Original (broken) line if ($request->user()->hasRole($roles) || $roles){
This says "if the user has the role OR roles exist" — which means any route with defined roles would let everyone pass, regardless of their actual permissions.
Fix: Reverse the Logic
Check if no roles are required or the user has the required role:
class Roles { public function handle($request, Closure $next) { $roles = $this->getRequiredRoleForRoute($request->route()); // Fixed: Allow access if no roles are required, or user has the role if (empty($roles) || $request->user()->hasRole($roles)){ return $next($request); } return redirect()->route('noPermissions'); } private function getRequiredRoleForRoute($route) { $actions = $route->getAction(); return isset($actions['roles']) ? $actions['roles'] : null; } }
4. Optional: Improve Login Error Handling
Right now, your postLogin method redirects to the root if login fails with no feedback. Add validation and error messages to make it user-friendly:
public function postLogin(Request $request) { // Validate input first $request->validate([ 'username' => 'required|string', 'password' => 'required|string', ]); $auth = Auth::guard('web')->attempt([ 'username' => $request->username, 'password' => $request->password, 'active' => 1 ]); if ($auth) { return redirect()->route('dashboard'); } // Redirect back to login with error message return redirect()->route('login')->withErrors([ 'login' => 'Invalid username/password, or your account is inactive.' ]); }
Final Checks
- Make sure your middleware is properly registered in
app/Http/Kernel.phpunder$routeMiddleware:protected $routeMiddleware = [ // ... 'authenticates' => \App\Http\Middleware\Authenticates::class, 'roles' => \App\Http\Middleware\Roles::class, ]; - Clear your route cache with
php artisan route:clearto ensure Laravel picks up the new routes.
内容的提问来源于stack exchange,提问作者user9085794

