Laravel 的用户认证是通过 Auth Facade 门脸实现的,手动认证可是使用 Auth::login() 或 Auth::attempt() 这两个方法实现.
以下内容纯属个人实现,也许有更优的实现方式.
对于识别前后端的用户,可以使用 Auth::guard() 方法实现,前端默认为 web 看守,Auth::guard('web') ,后端用户使用 admin 看守, Auth::guard('admin') .
1.新建 guard 看守
在 config/auth.php 中新建 admin 看守
'guards' => [ 'web' => [ 'driver' => 'session', 'provider' => 'users', ], 'api' => [ 'driver' => 'token', 'provider' => 'users', ], 'admin' => [ 'driver' => 'session', 'provider' => 'users' ] ]
看守的提供者 provider 不变,还是 users .
'providers' => [ 'users' => [ 'driver' => 'eloquent', 'model' => AppModelsUser::class, 'table' => 'users', ], // 'users' => [ // 'driver' => 'database', // 'table' => 'users', // ], ],
这样做的好处是前后端的用户可以放在一张 users 表中,只需要利用状态区分用户就好了,比如 user_status = 1 的是前端用户, user_status = 2 的是后端用户.
2. 新建两个中间件,区分前后端用户登录
将新建的中间件添加到 app/Http/Kernel.php 中
protected $routeMiddleware = [ .... 'adminVerify' => AppHttpMiddlewareAdminVerify::class, 'frontVerify' => AppHttpMiddlewareFrontVerify::class, ];
在区分前后端用户登录这个功能中,可以废弃默认 Auth 认证中间件 guest.
'guest' => AppHttpMiddlewareRedirectIfAuthenticated::class,
这样做的好处是简化了中间件的使用,不用两套系统公用一个 guest 中间件.
我们使用 adminVerify 中间件来做后端认证,所有的后端路由都必须通过这个中间件. adminVerify 中间件如下
<?php namespace AppHttpMiddleware; use Closure; use IlluminateSupportFacadesAuth; class AdminVerify { /** * Handle an incoming request. * * @param IlluminateHttpRequest $request * @param Closure $next * @return mixed */ public function handle($request, Closure $next) { $current_uri = $request->getRequestUri(); $ignore_uri = [ '/admin/login', '/admin/logout' ]; if (in_array($current_uri, $ignore_uri)) { return $next($request); } else { if (Auth::guard('admin')->check()) { return $next($request); } else { return redirect('/admin/login'); } } } }
使用 frontVerify 中间件来做前端认证,所有的前端路由都必须通过这个中间件. frontVerify 中间件如下
<?php namespace AppHttpMiddleware; use Closure; use IlluminateSupportFacadesAuth; class FrontVerify { /** * Handle an incoming request. * * @param IlluminateHttpRequest $request * @param Closure $next * @return mixed */ public function handle($request, Closure $next) { $current_uri = $request->getRequestUri(); $ignore_uri = [ '/login', '/logout' ]; if (in_array($current_uri, $ignore_uri)) { return $next($request); } else { if (Auth::guard('web')->check()) { return $next($request); } else { return redirect('/login'); } } } }
3. 路由设置
默认所有的前端路由都没有前缀,所有的后端路由都带有 admin 前缀. 路由设置如下.
// ==== 前后端登录 // 前端 Route::group(['middleware' => ['frontVerify']], function () { Route::get('/', 'FrontLoginController@index')->name('front_index'); Route::get('login', 'FrontLoginController@login'); Route::post('login', 'FrontLoginController@store')->name('front_login'); Route::get('logout', 'FrontLoginController@logout')->name('front_logout'); Route::get('login-success', 'FrontLoginController@success')->name('front_success'); }); // 后端 Route::group(['prefix' => 'admin', 'middleware' => ['adminVerify']], function () { Route::get('/', 'AdminLoginController@index')->name('admin_index'); Route::get('login', 'AdminLoginController@login'); Route::post('login', 'AdminLoginController@store')->name('admin_login'); Route::get('logout', 'AdminLoginController@logout')->name('admin_logout'); Route::get('login-success', 'AdminLoginController@success')->name('admin_success'); }); // ==== 前后端登录 END
前后端都有一个 login-success 页面,这两个页面的内容是一模一样的,除了文字不一样.
以下是后端页面的 login-success 页面
<h1>后端登录成功</h1> 我是 admin guard -- {{ IlluminateSupportFacadesAuth::guard('admin')->check() }} ===== 我是 web guard -- {{ IlluminateSupportFacadesAuth::guard('web')->check() }}
前端的 login-success 页面
<h1>前端登录成功</h1> 我是 admin guard -- {{ IlluminateSupportFacadesAuth::guard('admin')->check() }} ===== 我是 web guard -- {{ IlluminateSupportFacadesAuth::guard('web')->check() }}
路由列表中前端有一个首页 / ,后端也有一个默认的首页 /admin/,这两个首页的作用是验证未登录的用户是不能访问前后端的任何一个页面的,如果通过路由访问,并且是在没有登录的情况下,那么在中间件中就让其自动跳到对应的登录页面,具体可以看中间件的代码.
4 . 具体登录代码实现
4.1.1 前端登录
<?php namespace AppHttpControllersFront; use AppHttpControllersController; use IlluminateFoundationAuthAuthenticatesUsers; use IlluminateHttpRequest; use IlluminateSupportFacadesAuth; class LoginController extends Controller { // use AuthenticatesUsers; /** * LoginController constructor. */ public function __construct() { } public function index() { return view('front.index'); } public function login(Request $request) { return view('front.login'); } public function store(Request $request) { $credentials = $this->validate($request, [ 'phone' => 'required|max:255', 'password' => 'required' ]); $rs = $this->guard()->attempt($credentials); if ($rs) { return redirect()->route('front_success'); } else { return back(); } } public function logout(Request $request) { $this->guard()->logout(); $request->session()->flush(); return redirect()->route('front_login'); } public function success(Request $request) { return view('front.success'); } protected function guard() { return Auth::guard('web'); } }
4.1.2 后端登录
<?php /** * Created by PhpStorm. * User: nwei * Date: 2018/12/21 * Time: 16:19 */ namespace AppHttpControllersAdmin; use AppHttpControllersController; use IlluminateHttpRequest; use IlluminateSupportFacadesAuth; class LoginController extends Controller { /** * LoginController constructor. * @param string $redirectTo */ public function __construct() { } public function index() { return view('admin.index'); } public function login() { return view('admin.login'); } public function store(Request $request) { $credentials = $this->validate($request, [ 'phone' => 'required|max:255', 'password' => 'required' ]); $rs = $this->guard()->attempt($credentials); if ($rs) { return redirect()->route('admin_success'); } else { return back(); } } public function success() { return view('admin.success'); } public function logout(Request $request) { $this->guard()->logout(); $request->session()->flush(); return redirect('admin/login'); } protected function guard() { return Auth::guard('admin'); } }
4.2 登录结果
4.2.1 前端登录结果
4.2.2 开一个隐身模式,测试后端登录结果
测试成功!
类似博文:
https://segmentfault.com/a/1190000007716366
原文:https://blog.csdn.net/xiaobinqt/article/details/85230617