使用 Laravel Guards 登录后,如何限制用户不访问登录页面?

Posted

技术标签:

【中文标题】使用 Laravel Guards 登录后,如何限制用户不访问登录页面?【英文标题】:How can I restrict the user not to access login page after logged in with Laravel Guards? 【发布时间】:2020-12-17 23:59:07 【问题描述】:

我正在使用 Laravel 构建一个项目。我的代码一切正常,就在用户登录时,他可以访问仪表板,但问题是当我点击登录网址时,它会返回并再次显示登录表单页面,当我点击仪表板的网址时,它是显示仪表板。

我们知道在 Facebook 中登录后我们无法再次访问登录页面,但如果我们注销然后我们可以看到,所以我希望在我的项目中使用相同的功能。下面是我所做的代码,

路线

Route::prefix('/admin')->namespace('Admin')->group(function()

    // All the Admin Routes
    Route::match(['get','post'],'/','AdminController@login');
    Route::group(['middleware' => 'admin'], function () 
        Route::get('dashboard','AdminController@dashboard');
        Route::get('logout','AdminController@logout');
    );

);

控制器

 public function login(Request $request)
        if($request->isMethod('post'))

            $data = $request->all();
            // echo "<pre>";
            // print_r($data);
            // die;
            $this->validate($request,[
                'email'=>'required',
                'password'=>'required',
            ],
            );
            
            if(Auth::guard('admin')->attempt(['email' => $data['email'], 'password' => $data['password']]))
                return redirect('admin/dashboard');
            else
                // $request->session()->flash('error', 'Invalid email or password');
                Session::flash('error','Invalid email or password');
                return redirect()->back();
            

        
        return view('admin.admin_login');
    

    public function logout()
        Auth::guard('admin')->logout();
        return redirect('/admin');
    

中间件

public function handle($request, Closure $next)
    
        if(!Auth::guard('admin')->check())
            return redirect('/admin');
        
        return $next($request);
    

内核.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,
        '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,
        'admin' => \App\Http\Middleware\Admin::class,
    ];

【问题讨论】:

你是如何注册你的中间件的? 我已经在kernel.php中注册了 是的,那个文件里面有很多地方可以注册,需要提供你放的地方, 好的,我正在更新我的帖子 【参考方案1】:

guest 中间件分配给您不希望经过身份验证的用户访问的任何路由。你可以给它传递一个守卫的名字:

'guest:admin'

【讨论】:

你可以看到Route::match(['get','post'],'/','AdminController@login');你认为这将是做到这一点的完美途径 好吧,它可能不应该处理多个 HTTP 方法,但是是的;您不希望经过身份验证的用户到达您的任何路线都将使用guest 中间件,这就是它的用途 好的,这就是中间件的用途,祝你好运【参考方案2】:

你可以使用这种路由方式

Route::get('/login', function () 
    //
)->middleware('guest:admin');

或者像这样在控制器中使用


 public function __construct()
    
        $this->middleware('auth')->only(['edit']);
    

public function __construct()

     $this->middleware('guest:admin')->only('login');

我正在处理你的代码

class AdminController extends Controller

// Define Middleware here like this 
public function __construct()

     $this->middleware('guest:admin')->only('login');


public function login(Request $request)
        if($request->isMethod('post'))

            $data = $request->all();
            // echo "<pre>";
            // print_r($data);
            // die;
            $this->validate($request,[
                'email'=>'required',
                'password'=>'required',
            ],
            );
            
            if(Auth::guard('admin')->attempt(['email' => $data['email'], 'password' => $data['password']]))
                return redirect('admin/dashboard');
            else
                // $request->session()->flash('error', 'Invalid email or password');
                Session::flash('error','Invalid email or password');
                return redirect()->back();
            

        
        return view('admin.admin_login');
    

    public function logout()
        Auth::guard('admin')->logout();
        return redirect('/admin');
    

【讨论】:

你看到我的登录路径了吗Route::match(['get','post'],'/','AdminController@login'); 是的,我见过他们。您可以在您的 loginController 中的控制器中使用 /** * 创建一个新的控制器实例。 * * @return void */ public function __construct() $this->middleware('guest:admin')->except('logout'); 保护函数guard() return Auth::guard('admin'); 我注意到您对所有路由只使用一个控制器。你可以像 laravel auth 控制器一样使用它们。为每种方法分开。我已经这样使用它们了 否 此 AdminController 仅用于登录。结果和以前一样 问题出在你的控制器和路由上。我正在更新答案【参考方案3】:

为访问登录页面创建特殊中间件并设置cookie或在会话或cookie存在时创建会话路由必须重定向到仪表板否则显示登录页面

【讨论】:

【参考方案4】:

检查redirectifauthenticated.php

并根据需要设置路线

<?php

namespace App\Http\Middleware;

use Closure;
use Illuminate\Support\Facades\Auth;

class RedirectIfAuthenticated

    /**
     * Handle an incoming request.
     *
     * @param  \Illuminate\Http\Request  $request
     * @param  \Closure  $next
     * @param  string|null  $guard
     * @return mixed
     */
    public function handle($request, Closure $next, $guard = null)
     
      switch ($guard) 
        case 'admin':
          if (Auth::guard($guard)->check()) 
            return redirect()->route('admin.dashboard');
          
          break;
        case 'writer':
          if (Auth::guard($guard)->check()) 
            return redirect()->route('writer.dashboard');
          
          break;
        default:
          if (Auth::guard($guard)->check()) 
              return redirect('/home'); 
          
          break;
      

      return $next($request);
    

【讨论】:

以上是关于使用 Laravel Guards 登录后,如何限制用户不访问登录页面?的主要内容,如果未能解决你的问题,请参考以下文章

Laravel 5.3 Rest API 登录

[PHP] 浅谈 Laravel Authentication 的 guards 与 providers

如何在 Laravel 5.4 中添加自定义用户提供程序

firebase onAuthStateChanged&Navigation Guards的模式 - Quasar应用程序

Laravel 自定义多重身份验证

是否可以通过 [Web] Guard 使用 Laravel 资源?