使用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、访问注册、登录、登出、获取用户信息等接口