一、JWT概述:
(1)token 只是一种思路,一种解决用户授权问题的思考方式,基于这种思路,针对不同的场景可以有很多种的实现。
而在众多的实现中,JWT (JSON Web Token) 的实现最为流行.JWT 这个标准提供了一系列如何创建具体 token 的方法,
这些缘故方法和规范可以让我们创建 token 的过程变得更加合理和效率.
(2),JWT是一个字符串,我们在发起网络请求时,将其放在header或者url中,这样可以保证传递的数据被篡改时能被我们发现,保证安全性。
1. 使用 composer 安装
composer require tymon/jwt-auth 1.*@rc
2.1 发布配置文件
# 这条命令会在 config 下增加一个 jwt.php 的配置文件 php artisan vendor:publish --provider="TymonJWTAuthProvidersLaravelServiceProvider"
2.2 生成加密密钥
php artisan jwt:secret
2.3 更新你的模型
如果你使用默认的 User 表来生成 token,你需要在该模型下增加一段代码
<?php namespace App; use TymonJWTAuthContractsJWTSubject; use IlluminateNotificationsNotifiable; use IlluminateFoundationAuthUser as Authenticatable; class User extends Authenticatable implements JWTSubject # 这里别忘了加 { use Notifiable; // Rest omitted for brevity /** * Get the identifier that will be stored in the subject claim of the JWT. * * @return mixed */ public function getJWTIdentifier() { return $this->getKey(); } /** * Return a key value array, containing any custom claims to be added to the JWT. * * @return array */ public function getJWTCustomClaims() { return []; } }
2.4 注册两个 Facade
这两个 Facade 并不是必须的,但是使用它们会给你的代码编写带来一点便利。
config/app.php
'aliases' => [ ... // 添加以下两行 'JWTAuth' => 'TymonJWTAuthFacadesJWTAuth', 'JWTFactory' => 'TymonJWTAuthFacadesJWTFactory', ],
如果你不使用这两个 Facade,你可以使用辅助函数 auth ()
auth () 是一个辅助函数,返回一个 guard,暂时可以看成 Auth Facade。
// 如果你不用 Facade,你可以这么写 auth('api')->refresh(); // 用 JWTAuth Facade JWTAuth::parseToken()->refresh();
2.5 修改 auth.php
config/auth.php
'guards' => [ 'web' => [ 'driver' => 'session', 'provider' => 'users', ], 'api' => [ 'driver' => 'jwt', // 原来是 token 改成jwt 'provider' => 'users', ], ],
2.6 注册一些路由
注意:在 Laravel 下,route/api.php
中的路由默认都有前缀 api
。
Route::group([ 'prefix' => 'auth' ], function ($router) { Route::post('login', 'AuthController@login'); Route::post('logout', 'AuthController@logout'); Route::post('refresh', 'AuthController@refresh'); Route::post('me', 'AuthController@me'); });
2.7 创建 token 控制器
php artisan make:controller AuthController
AuthController
值得注意的是 Laravel 这要用 auth('api')
<?php namespace AppHttpControllers; use IlluminateSupportFacadesAuth; use AppHttpControllersController; class AuthController extends Controller { /** * Create a new AuthController instance. * 要求附带email和password(数据来源users表) * * @return void */ public function __construct() { // 这里额外注意了:官方文档样例中只除外了『login』 // 这样的结果是,token 只能在有效期以内进行刷新,过期无法刷新 // 如果把 refresh 也放进去,token 即使过期但仍在刷新期以内也可刷新 // 不过刷新一次作废 $this->middleware('auth:api', ['except' => ['login']]); // 另外关于上面的中间件,官方文档写的是『auth:api』 // 但是我推荐用 『jwt.auth』,效果是一样的,但是有更加丰富的报错信息返回 } /** * Get a JWT via given credentials. * * @return IlluminateHttpJsonResponse */ public function login() { $credentials = request(['email', 'password']); if (! $token = auth('api')->attempt($credentials)) { return response()->json(['error' => 'Unauthorized'], 401); } return $this->respondWithToken($token); } /** * Get the authenticated User. * * @return IlluminateHttpJsonResponse */ public function me() { return response()->json(auth('api')->user()); } /** * Log the user out (Invalidate the token). * * @return IlluminateHttpJsonResponse */ public function logout() { auth('api')->logout(); return response()->json(['message' => 'Successfully logged out']); } /** * Refresh a token. * 刷新token,如果开启黑名单,以前的token便会失效。 * 值得注意的是用上面的getToken再获取一次Token并不算做刷新,两次获得的Token是并行的,即两个都可用。 * @return IlluminateHttpJsonResponse */ public function refresh() { return $this->respondWithToken(auth('api')->refresh()); } /** * Get the token array structure. * * @param string $token * * @return IlluminateHttpJsonResponse */ protected function respondWithToken($token) { return response()->json([ 'access_token' => $token, 'token_type' => 'bearer', 'expires_in' => auth('api')->factory()->getTTL() * 60 ]); } }