zoukankan      html  css  js  c++  java
  • Laravel 的 API 认证系统 Passport 三部曲(二、passport的具体使用)

     

    96 
    GQ1994 
    2018.04.20 09:31 字数 1152 阅读 1316评论 0
    参考链接

    Laravel 的 API 认证系统 Passport 三部曲(一、passport安装+配置)

    Laravel 的 API 认证系统 Passport

    引言

    1. 在使用前要先了解Auth2.0的使用方式和原理Laravel 的用户认证系统
    2. passport是专门做api令牌授权的工具,这里有个问题是他不像auth一样可以定义多个guard来区分不同平台走不同的auth认证模块,他默认只走guard=api这个api认证模块。

    密码授权令牌的获取

    • 请求令牌
      创建密码授权的客户端后,就可以通过向用户的电子邮件地址和密码向 /oauth/token 路由发出 POST 请求来获取访问令牌。而该路由已经由 Passport::routes 方法注册,因此不需要手动定义它。如果请求成功,会在服务端返回的 JSON 响应中收到一个 access_token 和 refresh_token:

      $http = new GuzzleHttpClient;
      
      $response = $http->post('http://your-app.com/oauth/token', [
          'form_params' => [
              'grant_type' => 'password',
              'client_id' => 'client-id',
              'client_secret' => 'client-secret',
              'username' => 'taylor@laravel.com',
              'password' => 'my-password',
              'scope' => '',
          ],
      ]);
      
      return json_decode((string) $response->getBody(), true);
      

    私人访问令牌

    在你的应用程序发布个人访问令牌之前,你需要在 passport:client 命令后带上 --personal 参数来创建对应的客户端。如果你已经运行了 passport:install 命令,则无需再运行此命令:

    php artisan passport:client --personal
    

    创建个人访问客户端后,你可以使用 User 模型实例上的 createToken 方法来为给定用户发布令牌。
    createToken 方法接受令牌的名称作为其第一个参数和可选的 作用域 数组作为其第二个参数:

    $user = AppUser::find(1);
    
    // Creating a token without scopes...
    $token = $user->createToken('Token Name')->accessToken;
    
    // Creating a token with scopes...
    $token = $user->createToken('My Token', ['place-orders'])->accessToken;
    

    注意: 由于passport默认只可以走一个guard认证,当多平台的时候,可以使用auth2.0来辅助操作,首先使用Auth2.0验证该平台对应的guard(当然,驱动使用session))下其账号密码是否正确,验证通过之后再获取该用户实例并给予私人访问令牌,这样就做到了不同平台的令牌生成)

    验证令牌

    • 通过中间件

      Passport 包含一个 验证保护机制 可以验证请求中传入的访问令牌。配置 api 的看守器使用 passport 驱动程序后,只需要在需要有效访问令牌的任何路由上指定 auth:api 中间件:

      Route::get('/user', function () {
          //
      })->middleware('auth:api');
      
    • 我们实现方式

      由于passport只可以走api一个guard验证,也就是只可以走一个用户授权表,这里我们多平台多登陆授权表则只用上面的验证登陆肯定就不对了,如上所说我们结合auth2.0来进行分平台进行验证。

      1. 首先创建一个AuthApi中间键
      2. 在/app/Http/Kernel.php中注册AuthApi中间键

      eg:

      public function handle($request, Closure $next, $guard = null)
      {
          if (empty(Auth::guard($guard)->user())) {
              return response()->json(["message" => "Unauthenticated."], 401);
          }
      
          return $next($request);
      }
      

      protected $routeMiddleware = [
      'apiAuth' => ApiAuth::class,
      ......
      ];

      1. 使用的时候比如要使用guard=home的验证令牌,则中间件为“apiAuth:home”即可

    注销登录、定期检查过期token,销毁旧的token

    • 注销登录

      eg:

      /**
       * 登出程序操作.
       *
       * @return IlluminateHttpResponse
       */
      public function logout()
      {
          $user = $this->guard()->user();
          if (empty($user)) {
              return $this->sendError('暂未登录', ['暂未登录'], 403);
          }
      
          // 获取当前登陆用户的access_token的id
          $accessToken = $user->access_token;
      
          // 找到这条access_token并且将其删除
          $token = Token::find($accessToken);
          if (empty($token)) {
              return $this->sendError('暂无有效令牌', ['暂无有效令牌'], 403);
          }
      
          if (!empty($token->delete())) {
              return $this->sendResponse([], '退出成功!');
          } else {
              return $this->sendError('退出失败', ['退出失败'], 500);
          }
      }
      
    • 定期检查过期token(官方文档没给,个人做的优化)

      • 创建token生成事件的监听器来处理该用户当前客户端下的所有失效的token

        在“/app/Providers/EventServiceProvider.php”中的“$listen”数组中添加

        // 生成token,检查失效的进行删除
        'LaravelPassportEventsAccessTokenCreated' => [
            'AppListenersRevokeOldTokens',
        ],
        

        终端执行:

        php artisan event:generate
        

        提示:"Events and listeners generated successfully!"代表创建成功了

      • 执行删除失效token操作

        在 'AppListenersRevokeOldTokens'的handle方法中执行删除失效token操作

        Token::where('id', '!=', $event->tokenId)
            ->where('user_id', $event->userId)
            ->where('client_id', $event->clientId)
            ->where('expires_at', '<', Carbon::now())
            ->orWhere('revoked', true)
            ->delete();
  • 相关阅读:
    4header组件开发
    3组件骨架开发
    2项目目录设计
    1项目相关的一些简介
    21AJax与Comet
    20JSON
    获取特定筛选条件下数据的四分位点
    动态长度字符串的解析拆分问题
    myBase Desktop 7无限免费试用方法
    VBA 将Excel工作簿中所有表格进行一键排版
  • 原文地址:https://www.cnblogs.com/guiyishanren/p/10757623.html
Copyright © 2011-2022 走看看