使用tymon/jwt-auth包(https://packagist.org/packages/tymon/jwt-auth)
1、安裝
composer require tymon/jwt-auth
2、發布配置,運行以下命令以發布包配置文件:您現在應該有一個config/jwt.php
文件,允許您配置此包的基礎知識。
php artisan vendor:publish --provider="Tymon\JWTAuth\Providers\LaravelServiceProvider"
3、生成秘鑰
php artisan jwt:secret
這將.env
使用類似的內容更新您的文件JWT_SECRET=foobar
這是將用於簽署您的令牌的密鑰。這究竟如何發生將取決於您選擇使用的算法。
4、更新您的用戶模型
<?php namespace App\Models; use Illuminate\Foundation\Auth\User as Authenticatable; use Illuminate\Notifications\Notifiable; use Tymon\JWTAuth\Contracts\JWTSubject; class TestUser extends Authenticatable implements JWTSubject { use Notifiable; public $timestamps = false; /** * Get the identifier that will be stored in the subject claim of the JWT. * * @return mixed */ public function getJWTIdentifier() { // TODO: Implement getJWTIdentifier() method. return $this->getKey(); } /** * Return a key value array, containing any custom claims to be added to the JWT. * * @return array */ public function getJWTCustomClaims() { return []; } }
並新建test_user表
CREATE TABLE `test_users` ( `id` int NOT NULL AUTO_INCREMENT, `phone` char(11) COLLATE utf8mb4_general_ci NOT NULL, `password` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL, `sex` tinyint NOT NULL, PRIMARY KEY (`id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci;
5、配置身份驗證保護
注意:這僅在您使用 Laravel 5.2 及更高版本時有效。
在該config/auth.php
文件中,您需要進行一些更改以配置 Laravel 以使用jwt
防護來支持您的應用程序身份驗證。
對文件進行以下更改:
'defaults' => [ 'guard' => 'api', 'passwords' => 'users', ], ... 'guards' => [ 'api' => [ 'driver' => 'jwt', 'provider' => 'users', ], ],
這里我們告訴api
守衛使用jwt
驅動程序,我們將api
守衛設置為默認值。
我們現在可以使用 Laravel 內置的 Auth 系統,由 jwt-auth 完成幕后工作!
6、添加一些路由,使用了auth.jwt自定義的中間件
Route::post('login', [\App\Http\Controllers\TestUserController::class, 'login']); Route::post('register', [\App\Http\Controllers\TestUserController::class, 'register']); Route::group(['middleware' => ['auth.jwt']], function () { Route::get('logout', [\App\Http\Controllers\TestUserController::class, 'logout']); Route::get('user', [\App\Http\Controllers\TestUserController::class, 'getAuthUser']); Route::get('refresh', [\App\Http\Controllers\TestUserController::class, 'refresh']); });
7、創建控制器
php artisan make:controller TestUserController
8、添加以下內容
<?php namespace App\Http\Controllers; use App\Http\Response\BizFailResponse; use App\Http\Response\BizSuccessResponse; use App\Library\DataChecker; use App\Models\TestUser; use Illuminate\Http\Request; use Tymon\JWTAuth\Exceptions\JWTException; use Tymon\JWTAuth\Exceptions\TokenExpiredException; use Tymon\JWTAuth\JWTAuth; class TestUserController { public function register(Request $request) { $params = $request->input(); DataChecker::requireExpectParamIsNonEmptyStr($params, 'phone'); DataChecker::requireExpectParamIsNonEmptyStr($params, 'sex'); DataChecker::requireExpectParamIsNonEmptyStr($params, 'password'); $userInfo = TestUser::query()->where('phone', $params['phone'])->get()->toArray(); if (!empty($userInfo)){ return BizFailResponse::makeWithMsg("該賬號{$params['phone']}已被注冊"); } $user = new TestUser(); $user->phone = $params['phone']; $user->sex = $params['sex']; $user->password = bcrypt($params['password']); $user->save(); return BizSuccessResponse::makeWithData($user); } public function login(Request $request) { $input = $request->only('phone', 'password'); $jwt_token = null; if (!$jwt_token = auth()->attempt($input)) { return BizFailResponse::makeWithMsg('賬號或者密碼錯誤'); } return BizSuccessResponse::makeWithData(['token'=>$jwt_token]); } public function logout(Request $request) { try { auth()->invalidate(); return BizSuccessResponse::makeWithMsg('登出成功'); } catch (JWTException $exception) { return BizFailResponse::makeWithMsg('登出失敗'); } } public function refresh(){ return BizSuccessResponse::makeWithData(['token'=>auth()->refresh()]); } public function getAuthUser(Request $request) { $user = auth()->user(); return response()->json(['user' => $user]); } }
9、新建中間件,支持token校驗和過期自動刷新
php artisan make:middleware AuthJwtTokend
代碼如下:
<?php namespace App\Http\Middleware; use Closure; use Illuminate\Http\Request; use Illuminate\Support\Facades\Auth; use Symfony\Component\HttpKernel\Exception\UnauthorizedHttpException; use Tymon\JWTAuth\Exceptions\JWTException; use Tymon\JWTAuth\Exceptions\TokenExpiredException; use Tymon\JWTAuth\Http\Middleware\BaseMiddleware; /** * 驗證token,並且過期自動刷新 * Class AuthJwtToken * @package App\Http\Middleware */ class AuthJwtToken extends BaseMiddleware { /** * Handle an incoming request. * * @param \Illuminate\Http\Request $request * @param \Closure $next * @return mixed */ public function handle(Request $request, Closure $next) { $this->checkForToken($request); try { if ($this->auth->parseToken()->authenticate()){ return $next($request); } throw new UnauthorizedHttpException('jwt-auth', '該用戶未登錄'); }catch (TokenExpiredException $e){ try { $token = $this->auth->refresh(); Auth::guard('api')->onceUsingId($this->auth->manager()->getPayloadFactory()->buildClaimsCollection()->toPlainArray()['sub']); // 在響應頭中返回新的 token return $this->setAuthenticationHeader($next($request), $token); }catch (JWTException $e) { throw new UnauthorizedHttpException('jwt-auth', $e->getMessage()); } } } }
10、注冊自定義中間件
App\Http\Kernel中$routeMiddleware新增
// 自定義中間件 'auth.jwt' => AuthJwtToken::class
11、訪問注冊、登錄、登出、獲取用戶信息等接口