分析laravel8中的dingo与jwt鉴权

下面由laravel教程栏目给大家介绍laravel8中dingo与jwt鉴权,希望对需要的朋友有所帮助!

1 什么是dingo

dingo api包是给laravel和lumen提供的Restful的工具包,它可以与jwt组件一起配合快速的完成用户认证,同时对于数据和运行过程中所产生的异常能够捕获到并且可以做出对应的响应。
主要功能:

  1. Router Version 路由版本管理
  2. http Exception 异常处理
  3. response transform 转化响应格式
1 安装dingo

在laravel根目录下通过composer进行dingo扩展包的安装,具体命令如下:

composer require dingo/api

使用以下命令可以发布 API 的配置文件到 config 文件下:

php artisan vendor:publish --provider="DingoApiProviderLaravelServiceProvider"
2 配置dingo

关于dingo的api配置信,我们可以在.env文件中进行配置

# dingo # API_SUBTYPE —— 项目的简称; API_SUBTYPE=lms # API_PREFIX —— 与 API_DOMAIN 二选一,路由的前缀,例如设置为 api API_PREFIX=api # 定义版本 API_VERSION=v1 # 是否开启调试模式 API_DEBUG=true

关于dingo的详细配置请查看相关文档:https://learnku.com/docs/dingo-api/2.0.0/Configuration/1444

2 什么是JWT

jwt全称JSON Web Tokens ,是一个非常轻巧的规范,这个规范允许我们使用jwt在用户和服务器之间传递安全可靠的信息,他的主要使用场景为:认证与数据交换

1 安装JWT

在laravel根目录下通过composer进行jwt扩展包的安装,具体命令如下:

composer require tymon/jwt-auth

使用以下命令可以发布 API 的配置文件到 config 文件下:

php artisan vendor:publish --provider="TymonJWTAuthProvidersLaravelServiceProvider"
2 配置JWT

在.env文件中生成jwt加密秘钥,具体命令如下:

php artisan jwt:secret

修改config/api.php配置

'auth' => [     'jwt' => 'DingoApiAuthProviderJWT', ],

修改config/auth.php配置

'defaults' => [         #注:这里修改改了默认的配置,默认是web         'guard' => 'api',         'passwords' => 'users',     ],     'guards' => [         'web' => [             'driver' => 'session',             'provider' => 'users',         ],          'api' => [             'driver' => 'jwt',             'provider' => 'users',             'hash' => false,         ],     ],

关于jwt的详细配置请查看相关文档:https://jwt-auth.readthedocs.io/en/develop/

3 相关代码演示

创建RefreshToken中间件,用于令牌过期刷新

namespace AppHttpMiddleware;  use Closure; use IlluminateSupportFacadesAuth; use IlluminateHttpRequest; use SymfonyComponentHttpKernelExceptionUnauthorizedHttpException; use TymonJWTAuthExceptionsJWTException; use TymonJWTAuthExceptionsTokenExpiredException; use TymonJWTAuthHttpMiddlewareBaseMiddleware;  class RefreshToken extends BaseMiddleware {     /**      * Handle an incoming request.      *      * @param  IlluminateHttpRequest  $request      * @param  Closure  $next      * @return mixed      */     public function handle(Request $request, Closure $next)     {         // 检查此次请求中是否带有 token,如果没有则抛出异常。         $this->checkForToken($request);          // 使用 try 包裹,以捕捉 token 过期所抛出的 TokenExpiredException  异常         try {             // 检测用户的登录状态,如果正常则通过             if ($this->auth->parseToken()->authenticate()) {                 return $next($request);             }             throw new UnauthorizedHttpException('jwt-auth', '未登录');         } catch (TokenExpiredException $exception) {             // 此处捕获到了 token 过期所抛出的 TokenExpiredException 异常,我们在这里需要做的是刷新该用户的 token 并将它添加到响应头中             try {                 // 刷新用户的 token                 $token = $this->auth->refresh();                 // 使用一次性登录以保证此次请求的成功                 Auth::guard('api')                     ->onceUsingId($this->auth->manager()                         ->getPayloadFactory()                         ->buildClaimsCollection()                         ->toPlainArray()['sub']);             } catch (JWTException $exception) {                 // 如果捕获到此异常,即代表 refresh 也过期了,用户无法刷新令牌,需要重新登录。                 throw new UnauthorizedHttpException('jwt-auth', $exception->getMessage());             }         }          // 在响应头中返回新的 token         return $this->setAuthenticationHeader($next($request), $token);     } }

User模型需要实现两个方法:getJWTIdentifier()和getJWTCustomClaims()

<?php  namespace AppModels;  use IlluminateContractsAuthMustVerifyEmail; use IlluminateFoundationAuthUser as Authenticatable; use IlluminateNotificationsNotifiable; use TymonJWTAuthContractsJWTSubject;  class User extends Authenticatable implements JWTSubject {     use Notifiable;      public $table = "user";      /**      * The attributes that are mass assignable.      *      * @var array      */     protected $fillable = [         'name', 'email', 'password','phone','status','create_time','addr_id'     ];      /**      * The attributes that should be hidden for arrays.      *      * @var array      */     protected $hidden = [         'password', 'remember_token',     ];      /**      * The attributes that should be cast to native types.      *      * @var array      */     protected $casts = [ //        'email_verified_at' => 'datetime',     ];      /**      * 指示是否自动维护时间戳      *      * @var bool      */     public $timestamps = false;      public function getJWTIdentifier()     {         return $this->getKey();     }     public function getJWTCustomClaims()     {         return [];     } } ?>

创建UserController用于鉴权等相关操作

<?php  namespace AppHttpControllersApiV1;  use AppHttpControllersController; use AppModelsUser; use DingoApiRoutingHelpers; use IlluminateHttpRequest;  class UserController extends Controller {     use Helpers;      public function __construct()     {        //除去token验证的方法        $this->middleware('refresh.token', [             'except' => [                 'login',             ],         ]);     }       /**用户登录      * @param Request $request      * @return IlluminateHttpJsonResponse|void      */     public function login(Request $request)     {         $phone = $request->get('phone');          $user = User::where('phone', $phone)->first();  //        //attempt貌似无法验证其他字段,如需用其他字段鉴权使用login() //        $credentials = request(['name','password']); //        if (!$token = auth()->attempt($credentials)) { //            return response()->json(['error' => 'Unauthorized'], 401); //        }          //只要是user实例就可以通过login鉴权         if (! $token = auth()->login($user)) {             return response()->json([                 "restful" => false,                 "message" => "账号错误",             ]);         }          //获取用户信息         $user = $this->user();         $key = "user::info::".$user->id;         //Redis缓存用户信息3600秒         Redis::set($key,serialize($user->original),"EX",3600);          return $this->respondWithToken($token);     }      /**获取用户      * Get the authenticated User.      *      * @return IlluminateHttpJsonResponse      */     public function user()     {         return response()->json(auth()->user());     }      /**用户退出      * Log the user out (Invalidate the token).      *      * @return IlluminateHttpJsonResponse      */     public function logout()     {         auth()->logout();          return response()->json(["message" => "退出成功"]);     }      /**用户登录状态刷新      * Refresh a token.      * @return IlluminateHttpJsonResponse      */     public function refresh()     {         return $this->respondWithToken(auth()->refresh());     }      /**返回值      * @param $token      * @return array      */     protected function respondWithToken($token)     {         return [             'access_token' => $token,             'token_type' => 'Bearer',             'expires_in' => auth()->factory()->getTTL() * 60,             'restful' => true         ];     } }

© 版权声明
THE END
喜欢就支持一下吧
点赞12 分享