【问题标题】:Laravel 5.3 Passport API unauthenticated in Postman using personal access tokensLaravel 5.3 Passport API 在 Postman 中使用个人访问令牌未经身份验证
【发布时间】:2017-02-11 12:48:03
【问题描述】:

我已经按照此处的文档使用护照设置了 Laravel:https://laravel.com/docs/5.3/passport

有些人使用 oAuth 实现询问过这个问题,但我尝试使用个人访问令牌而不是 oAuth。一个建议是删除 auth 中间件,但显然这会使应用程序完全开放,因此任何人都可以提出请求。

我有以下路线(在 routes/api.php 中):

Route::get('/test', function(){
    return 'returned string from test route';
})->middleware('auth:api');

如果我删除了 auth 中间件,这样路由就可以正常工作,但是当再次启用 auth 中间件时,我在邮递员中收到以下错误:

{"error":"Unauthenticated."}

这些是通过邮递员发送的标头:

GET /api/test HTTP/1.1
Host: localhost:8000
Authorization: Bearer eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiIsImp0aSI6ImU4ZmY5MDMwY2EyM2E2MDYwODViN2Y3ZWNiMzcxNDY1MzQxNDViNTk4ODU4NmZhNDljYzU2YjMzYWZiNzhkYTk5OTIwZWMzYzEwNTBkNjZjIn0.eyJhdWQiOiIyIiwianRpIjoiZThmZjkwMzBjYTIzYTYwNjA4NWI3ZjdlY2IzNzE0NjUzNDE0NWI1OTg4NTg2ZmE0OWNjNTZiMzNhZmI3OGRhOTk5MjBlYzNjMTA1MGQ2NmMiLCJpYXQiOjE0NzU1MDMxNjUsIm5iZiI6MTQ3NTUwMzE2NSwiZXhwIjowLCJzdWIiOiIxIiwic2NvcGVzIjpbXX0.IpzKK29dJCpliUXQvPRss87kGFngFcXXwV3jRwhbZOZLxl-4UV70cBsSigmqUuBsHQ4onVl_Cjcq6cEmMFvTZZr7D9AtY3EmScvMPjoFh4KQ3wgd5CoyWfcLQgoBxbElNxL0xW2fIQhpeQd_8Yz_Pr5BByGVTpxfg4JJZ4PzovvZsa2R3izYtqw6-qeurQOtsfOnot5uoLDeDDc76klifnfHfOcNZSoIFGNP3gIGKYBe6lfFuDViR_mQkwQS5_UmERt3GSkEvJjGMtwcRjWY7VPAJ4tvWLnyLw0roGU2e37L0wsqfJ8OrG0Cipv-anXAW_utSo-fiVMr8ZeAWIPguq73Zd44x95YY3nNPOKD5dVIRZM7rQgdhjIwTEz1ggtSXLp-Fu3QOtXaHUahCHvjOTdiTYEa-GR4TZ5wGzt-aRhjdBB7WTe0C6T9ZWVwQr0kJk8AxW6ne87wwJYp_shGunTclZ3SCq5VYg2K_MclbJl65-dT8x-nwqg0lqfNx9s1wmtryrMFIPoBEyaGNEK1aWGHKq418-BIQ1_UAhcHHtEXclWvsGWwhyo3aso-E-sCN2o_IkYvSboIsdFAIXvDvQmoAwis6f1J57zWH8AW1ynCFcBgzBDjIyiaCE5nqtb_4zbEXr8L1EbcllbtZkq3vd9w996kO7xlpBEWwPY8IWg
Accept: application/json
Cache-Control: no-cache
Postman-Token: 6bc483b2-23df-acce-7eef-5a443f8f5d45

【问题讨论】:

  • 我也有同样的问题。不明白为什么:(
  • @ba me too 2017 年 5 月 11 日
  • @Rabb-bit 您使用的是 32 位版本的 PHP 吗?如果是这样,那是你的问题......好吧,2038 年的问题en.wikipedia.org/wiki/Year_2038_problem 要么升级到 64 位版本的 PHP,要么将令牌过期时间更改为小于 2038 年(目前是从今天开始 + 100 年)

标签: php laravel laravel-5.3


【解决方案1】:

我遇到了这个问题......两个小时后。发生了一些非常奇怪的事情,就我而言,我认为 Postman 是罪魁祸首。

检查收到的标头以排除它:

Route::get('/test', function(){
    dd( Request::header());
})/*->middleware('auth:api')*/; //disable auth middleware to inspect header

这是我发现的奇怪之处:

.........
"authorization" => array:1 [
    0 => b"Bearer eyJ0eXAiOiJKV1QiLCJhbGciOiJ ................

Bearer ACCESS_TOKEN 之前的“b”到底是什么? 我再次输入它,它消失了,auth 中间件开始工作。

准确检查标头,然后添加中间件。这可能只是原因!

【讨论】:

    【解决方案2】:

    请检查令牌是否正确复制,我在复制个人令牌时总是观察到,最后也复制了一个“关闭”字样。 eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiIsImp0aSI6ImU4ZmY5MDMwY2EyM2E2MDYwODViN2Y3ZWNiMzcxNDY1MzQxNDViNTk4ODU4NmZhNDljYzU2YjMzYWZiNzhkYTk5OTIwZWMzYzEwNTBkNjZjIn0.eyJhdWQiOiIyIiwianRpIjoiZThmZjkwMzBjYTIzYTYwNjA4NWI3ZjdlY2IzNzE0NjUzNDE0NWI1OTg4NTg2ZmE0OWNjNTZiMzNhZmI3OGRhOTk5MjBlYzNjMTA1MGQ2NmMiLCJpYXQiOjE0NzU1MDMxNjUsIm5iZiI6MTQ3NTUwMzE2NSwiZXhwIjowLCJzdWIiOiIxIiwic2NvcGVzIjpbXX0.IpzKK29dJCpliUXQvPRss87kGFngFcXXwV3jRwhbZOZLxl-4UV70cBsSigmqUuBsHQ4onVl_Cjcq6cEmMFvTZZr7D9AtY3EmScvMPjoFh4KQ3wgd5CoyWfcLQgoBxbElNxL0xW2fIQhpeQd_8Yz_Pr5BByGVTpxfg4JJZ4PzovvZsa2R3izYtqw6-qeurQOtsfOnot5uoLDeDDc76klifnfHfOcNZSoIFGNP3gIGKYBe6lfFuDViR_mQkwQS5_UmERt3GSkEvJjGMtwcRjWY7VPAJ4tvWLnyLw0roGU2e37L0wsqfJ8OrG0Cipv-anXAW_utSo-fiVMr8ZeAWIPguq73Zd44x95YY3nNPOKD5dVIRZM7rQgdhjIwTEz1ggtSXLp-Fu3QOtXaHUahCHvjOTdiTYEa-GR4TZ5wGzt-aRhjdBB7WTe0C6T9ZWVwQr0kJk8AxW6ne87wwJYp_shGunTclZ3SCq5VYg2K_MclbJl65-dT8x-nwqg0lqfNx9s1wmtryrMFIPoBEyaGNEK1aWGHKq418-BIQ1_UAhcHHtEXclWvsGWwhyo3aso-E-sCN2o_IkYvSboIsdFAIXvDvQmoAwis6f1J57zWH8AW1ynCFcBgzBDjIyiaCE5nqtb_4zbEXr8L1EbcllbtZkq3vd9w996kO7xlpBEWwPY8IWg Copy

    如果不是您的情况,请检查该令牌是否存在,或生成一个新令牌。您可以使用这种格式来保护这样的路线

    Route::middleware('auth:api')->get('/home', function(){
        return 'test';
    });
    

    【讨论】:

      【解决方案3】:
      • 首先,切勿修改供应商文件,除非您有完全正当的理由这样做,并且您希望看到实现的功能或您在您正在使用的软件包。

      • JWT 上的过期时间可能已经设置为一旦完成就过期。您可以使用以下链接检查访问令牌的“ttl”(生存时间)字段:

      https://jwt.io/

      如果您发现您的令牌在创建时过期,您可以转到您的 app\providers\AuthServiceProvider.php 类并在使用 Passport 类时添加这些方法:

      use Carbon\Carbon;
      use Laravel\Passport\Passport;
      ...
      
      Class AuthServiceProvider extends ServiceProvider {
          ...
          ...
      
          public function boot() {
              $this->registerPolicies();
              Passport::routes();
              Passport::tokensExpireIn(Carbon::now()->addYears(20));//You can also use addDays(10)
              Passport::refreshTokensExpireIn(Carbon::now()->addYears(20));//You can also use addDays(10) 
              Passport::pruneRevokedTokens(); //basic garbage collector
          }
      }
      
      • 确保您使用的是最新版本的 Passport 目前我使用的是 1.0.8 版本,但我可能已经过时了,因为他们和社区每隔几周就会不断推出新的修订版。

      以下是与此问题相关的一些相关问题的链接。您或许可以在以下链接之一中找到您的答案。如果上面提到的不是你要找的。

      Passport - "Unauthenticated." - Laravel 5.3

      非常详细

      https://github.com/laravel/passport/issues/151

      【讨论】:

        【解决方案4】:

        在passport.php中有两个函数

        public static function tokensExpireIn(DateTimeInterface $date = null)
        {
            if (is_null($date)) {
                return static::$tokensExpireAt
                                ? Carbon::now()->diff(static::$tokensExpireAt)
                                : new DateInterval('P100Y');
            } else {
                static::$tokensExpireAt = $date;
            }
        
            return new static;
        }
        
        /**
         * Get or set when refresh tokens expire.
         *
         * @param  \DateTimeInterface|null  $date
         * @return \DateInterval|static
         */
        public static function refreshTokensExpireIn(DateTimeInterface $date = null)
        {
            if (is_null($date)) {
                return static::$refreshTokensExpireAt
                                ? Carbon::now()->diff(static::$refreshTokensExpireAt)
                                : new DateInterval('P100Y');
            } else {
                static::$refreshTokensExpireAt = $date;
            }
        
            return new static;
        }
        

        您必须将 P100Y 更改为 P1Y。在第 101 行的 PassportserviceProvider.php 中也有代码

         $server->enableGrantType(
                        new PersonalAccessGrant, new DateInterval('P100Y')
                    );
        

        将 P100Y 更改为 P1Y。希望对你有帮助:)

        【讨论】:

        • 为什么在 Windows 下会失败,为什么 P1Y 可以工作?
        • 您永远不想更改供应商文件夹中的文件。如果您认为这样做合适,那么请确保有一个很好的理由。同时,如果您希望在 DateInterval 方法中更改或修改 P100Y,那么您可以在供应商文件夹之外进行。
        • @AndreF。如果我错了,请纠正我,但我相信 P100Y 是一个合法的错误。在我最近下载的 Laravel 中,已将其更改为 P1Y。这不是编辑文件的充分理由吗?
        • @JacobHenning 在撰写该评论时,每个人仍在了解该问题并试图将其识别为合法或故意。因为据我所知,许多人只是在寻找解决修改供应商文件夹的问题(没有清楚地知道你在做什么,没有明确的目标,也没有了解你需要做什么来完成它)被考虑鲁莽。自撰写该评论以来,该修复程序是在 5.3 和 5.4 版本之间引入的。记住帖子和技术版本的时间总是有帮助的
        猜你喜欢
        • 2018-03-22
        • 2017-09-01
        • 1970-01-01
        • 2017-05-13
        • 1970-01-01
        • 1970-01-01
        • 2018-01-05
        • 2017-01-06
        • 2020-11-04
        相关资源
        最近更新 更多