Laravel 5.2 中本身自带了 auth 认证,也是支持多用户的,但是项目使用 Angular,所以后端只需要以接口的形式提供 json api 就可以了,这里就需要使用 JWT 来进行用户认证了,网上普遍的方式是使用 JWT-Auth 框架来进行 JWT 认证,但是发现 5.9 版本不支持多用户认证,1.0 之后才支持。但是由于 1.0 版本是 alpha 版本,所以 github 上并没有其相关文档,找了半天发现作者在某个 issue 里面提到了多用户的使用方法,遂在这里整理记录一下。
1 在 composer.json
文件的 require 中添加如下行来引入 JWT-Auth
"require": { ... "tymon/jwt-auth": "^1.0@dev", ... } |
2 comfig/app.php 配置
providers
下添加
Tymon\JWTAuth\Providers\LaravelServiceProvider::class
|
aliases
下添加
'JWTAuth' => Tymon\JWTAuth\Facades\JWTAuth::class, 'JWTFactory' => Tymon\JWTAuth\Facades\JWTFactory::class, |
3 terminal 下执行 php artisan vendor:publish --provider="Tymon\JWTAuth\Providers\LaravelServiceProvider"
在 config 下生成 jwt.php
配置文件
4 terminal 下执行 php artisan jwt:secret
生成加密密钥
5 config/auth.php 设置相关参数
'guards' => [ ... 'admin' => [ 'driver' => 'jwt', 'provider' => 'admins', ], ], 'providers' => [ ... 'admins' => [ 'driver' => 'eloquent', 'model' => App\Models\Admin::class, ], ], |
6 route.php 中添加登录相关路由
Route::post('/auth/login', 'AuthController@login');
|
7 AuthController.php 中添加登录逻辑
namespace App\Http\Controllers\Admin; use App\Models\Admin; use Illuminate\Http\Request; use App\Http\Controllers\Controller; use Illuminate\Foundation\Auth\ThrottlesLogins; use Illuminate\Foundation\Auth\AuthenticatesAndRegistersUsers; use Validator; use JWTAuth; use Tymon\JWTAuth\Exceptions\JWTException; use Auth; class AuthController extends Controller{ use AuthenticatesAndRegistersUsers, ThrottlesLogins; protected $guard = 'admin'; protected $username = 'username'; // 注册 public function register(Request $request){ $validator = $this->validator($request->all()); if ($validator->fails()) { return $this->errorBadRequest($validator->messages(), 500); } $user = $this->create($request->all()); $credentials = [ 'username' => $request['username'], 'password' => $request['password'], ]; $token = Auth::guard($this->getGuard())->attempt($credentials); return $this->JSON(compact('token')); } // 登录 public function login(Request $request){ $this->validateLogin($request); $throttles = $this->isUsingThrottlesLoginsTrait(); if ($throttles && $lockedOut = $this->hasTooManyLoginAttempts($request)) { $this->fireLockoutEvent($request); return $this->sendLockoutResponse($request); } $credentials = $this->getCredentials($request); // 这里改用 JWT-Auth 进行认证 if ($token = Auth::guard($this->getGuard())->attempt($credentials)) { return $this->handleUserWasAuthenticated($request, $throttles, $token); } if ($throttles && ! $lockedOut) { $this->incrementLoginAttempts($request); } return $this->sendFailedLoginResponse($request); } // 刷新 token public function refreshToken(){ $oldToken = JWTAuth::getToken(); $token = JWTAuth::refresh($oldToken); return $this->JSON(compact('token')); } // 退出登录 public function logout(){ Auth::guard($this->getGuard())->logout(); return $this->JSON(array('status' => 'success')); } protected function validator(array $data){ return Validator::make($data, Admin::$rules); } protected function create(array $data){ return Admin::create([ 'username' => $data['username'], 'password' => bcrypt($data['password']), ]); } protected function handleUserWasAuthenticated(Request $request, $throttles, $token){ if ($throttles) { $this->clearLoginAttempts($request); } if (method_exists($this, 'authenticated')) { return $this->authenticated($request, Auth::guard($this->getGuard())->user(), $token); } return redirect()->intended($this->redirectPath()); } protected function authenticated($request, $user, $token){ return self::JSON([ 'user' => $user, 'token' => $token ]); } protected function sendFailedLoginResponse(Request $request){ return self::errorBadRequest($this->getFailedLoginMessage()); } } |
在 AuthController
中的 guard 属性可以指定在 auth.php
中声明的认证方式。
在其它需要认证才能访问的 controller 中可以使用中间件来判断
public function __construct(){ $this->middleware('auth:admin'); } |
auth 中间件 Authenticate.php
public function handle($request, Closure $next, $guard = null){ if (Auth::guard($guard)->guest()) { return response('Unauthorized.', 401); } return $next($request); } |