Laravel 5.4 401/未通过身份验证使用 Passport 和多种令牌类型
Laravel 5.4 401/Unauthenticated using Passport and multiple token types
这方面的背景故事,我一直在按照文档中的说明进行操作:https://laravel.com/docs/5.4/passport
我有
- Laravel 5.4
- "laravel/passport":来自作曲家的“^3.0”
- 本地 Mac osx 运行 Mamp pro, Php 7.0.15
我正在调用 routes/api 中的示例用户路由。php
Route::get('/user', function () {
return 'testing';
})->middleware('auth:api');
Postman curl Header(从 Postman 中的代码导出中提取):
CURLOPT_HTTPHEADER => array(
"accept: application/json",
"authorization: Bearer eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiIsImp0aSI6ImM3ZmI2ZmNmMWFkOGQ0NjFkNTdhMWU2NjFiYjhhOThmOTJhOTBkMDFkNDkwZDFjNDRkNDg5MTdlYjJiZWYyMDlkNjNmOTQwMjIxNTljZWI5In0.eyJhdWQiOiIxIiwianRpIjoiYzdmYjZmY2YxYWQ4ZDQ2MWQ1N2ExZTY2MWJiOGE5OGY5MmE5MGQwMWQ0OTBkMWM0NGQ0ODkxN2ViMmJlZjIwOWQ2M2Y5NDAyMjE1OWNlYjkiLCJpYXQiOjE1MDE3OTQ2NjIsIm5iZiI6MTUwMTc5NDY2MiwiZXhwIjoxNTMzMzMwNjYyLCJzdWIiOiIxIiwic2NvcGVzIjpbImFwaS1hY2Nlc3MiXX0.CPGM4PIKJBeiJvokuDzShz_1CnqHlnFIML-tWoBCn5GcijMXmQkWOHzTI8QwTws2h719TGA4hemXDljjqoZB0LiztAx2JZ3OhjNS-MhrMNujnTJUbvkXAVfcRdybhlDEWof_iboLICQTYNTslX1iw-2DCyFMh8gB4INAKUhpvzA955ALB-ZunKrjSNKdRkgtZRe0t6VyJf9LwzgjIAfSKoi_qRis36KD7hcf0Id_iWZkhvS-ZfuM5eUpzUooUe0rb4rkYYEYndlHlY7-uuZPlzmPMpaJTR4AW1CLkaK5Ic7fde1x1kk2duW_Znd9ki2YBP0kw7ifAmg2DaM5r2-0kEx_1iFuCIxE8QJns1aIm3XjWoOApovt7V6-s3yJZK3xlIDCjFI-C59RHiVSabh-hKdX4elvSL9taSQyuramPZPpsne9SUh4KCWul0iHoNjFdFJEut_TUBWyUPtD3J7gg6P97uRS_THDAUHMo2UYVhlnu9PV8SvbvjGj3OeaaH7ZbzWQCYKbqsLZAZ2mnJlFhTMghbaC2s_MND1zlRm7w9btmihxVW714NUbH8UAwSvrtIYYQ0itevZ59TLiAXprjmjkhiFkrhdX4bUje4uNEbLYawkZI-1o82IExW9D8kCYpOWOZdWTCLgmaE2wXcf-DTCV-9vDWRAdX1YmP4JbRsc",
"cache-control: no-cache",
"content-type: multipart/form-data; boundary=----WebKitFormBoundary7MA4YWxkTrZu0gW",
"postman-token: 2ec7a2c8-3489-812d-4638-ebb7dc62aeb1"
),
我有 1 个使用 Vue 组件生成的个人访问令牌
我已经检查过我将令牌有效期设置为 1 年,这反映在数据库中。
我的AuthServiceProvider.php
Passport::routes();
// TODO MAKE THEM LAST A LONG TIME
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::tokensCan([
'api-access' => 'Access Complete API',
]);
我的RouteServiceProvider.php(map函数中调用了mapApiRoutes)
protected function mapApiRoutes()
{
Route::group([
'namespace' => $this->namespace,
'prefix' => 'api',
], function ($router) {
require base_path('routes/api.php');
});
}
我的Kernel.php路由中间件
protected $routeMiddleware = [
'auth' => \Illuminate\Auth\Middleware\Authenticate::class,
'auth.basic' => \Illuminate\Auth\Middleware\AuthenticateWithBasicAuth::class,
'bindings' => \Illuminate\Routing\Middleware\SubstituteBindings::class,
'can' => \Illuminate\Auth\Middleware\Authorize::class,
'guest' => \App\Http\Middleware\RedirectIfAuthenticated::class,
'throttle' => \Illuminate\Routing\Middleware\ThrottleRequests::class,
];
-- 编辑 -- 经过更多研究
我正在使用 postman 来测试我的 api 身份验证,每次尝试都会得到 401。我已经尝试过 Personal Access Client 和 Password Grant Client,两者都有同样的问题。在查看了它们之后,我意识到它们都使用 Authorization Bearer [token] 格式。
所以我开始在 Passport 源中的各种文件中注销。
在TokenGuard.php
public function user(Request $request) {
Log::info('TokenGuard: '. $request);
if ($request->bearerToken()) {
return $this->authenticateViaBearerToken($request);
} elseif ($request->cookie(Passport::cookie())) {
return $this->authenticateViaCookie($request);
}
}
日志如下所示:
[2017-08-10 20:50:20] local.INFO: TokenGuard 93: GET /api/user HTTP/1.1
Accept: application/json
Accept-Encoding: gzip, deflate
Cache-Control: no-cache
Connection: keep-alive
Content-Type: application/json
Host: url.com:8888
Postman-Token: 66707fe5-8f6e-4920-948b-2804a76d4a65
User-Agent: PostmanRuntime/6.2.5
[2017-08-10 20:50:20] local.INFO: TokenGuard 93: GET /api/user HTTP/1.1
Accept: application/json
Accept-Encoding: gzip, deflate
Cache-Control: no-cache
Connection: keep-alive
Content-Type: application/json
Host: url.com:8888
Postman-Token: 66707fe5-8f6e-4920-948b-2804a76d4a65
User-Agent: PostmanRuntime/6.2.5
缺少的是请求的 Bearer [token] 部分。 TokenGuard 代码块是 运行 和 if/else。这就是我认为失败发生的地方。
它不应该也被注销吗?由于 Bearer Token 丢失 If/Else 失败,因此 return 401 是有意义的。
为什么我的 Token 会被从请求中剥离。
将此添加到项目 public 目录下的 .htaccess
文件中:
RewriteEngine on
RewriteCond %{HTTP:Authorization} ^(.*)
RewriteRule .* - [e=HTTP_AUTHORIZATION:%1]
这方面的背景故事,我一直在按照文档中的说明进行操作:https://laravel.com/docs/5.4/passport
我有
- Laravel 5.4
- "laravel/passport":来自作曲家的“^3.0”
- 本地 Mac osx 运行 Mamp pro, Php 7.0.15
我正在调用 routes/api 中的示例用户路由。php
Route::get('/user', function () {
return 'testing';
})->middleware('auth:api');
Postman curl Header(从 Postman 中的代码导出中提取):
CURLOPT_HTTPHEADER => array(
"accept: application/json",
"authorization: Bearer eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiIsImp0aSI6ImM3ZmI2ZmNmMWFkOGQ0NjFkNTdhMWU2NjFiYjhhOThmOTJhOTBkMDFkNDkwZDFjNDRkNDg5MTdlYjJiZWYyMDlkNjNmOTQwMjIxNTljZWI5In0.eyJhdWQiOiIxIiwianRpIjoiYzdmYjZmY2YxYWQ4ZDQ2MWQ1N2ExZTY2MWJiOGE5OGY5MmE5MGQwMWQ0OTBkMWM0NGQ0ODkxN2ViMmJlZjIwOWQ2M2Y5NDAyMjE1OWNlYjkiLCJpYXQiOjE1MDE3OTQ2NjIsIm5iZiI6MTUwMTc5NDY2MiwiZXhwIjoxNTMzMzMwNjYyLCJzdWIiOiIxIiwic2NvcGVzIjpbImFwaS1hY2Nlc3MiXX0.CPGM4PIKJBeiJvokuDzShz_1CnqHlnFIML-tWoBCn5GcijMXmQkWOHzTI8QwTws2h719TGA4hemXDljjqoZB0LiztAx2JZ3OhjNS-MhrMNujnTJUbvkXAVfcRdybhlDEWof_iboLICQTYNTslX1iw-2DCyFMh8gB4INAKUhpvzA955ALB-ZunKrjSNKdRkgtZRe0t6VyJf9LwzgjIAfSKoi_qRis36KD7hcf0Id_iWZkhvS-ZfuM5eUpzUooUe0rb4rkYYEYndlHlY7-uuZPlzmPMpaJTR4AW1CLkaK5Ic7fde1x1kk2duW_Znd9ki2YBP0kw7ifAmg2DaM5r2-0kEx_1iFuCIxE8QJns1aIm3XjWoOApovt7V6-s3yJZK3xlIDCjFI-C59RHiVSabh-hKdX4elvSL9taSQyuramPZPpsne9SUh4KCWul0iHoNjFdFJEut_TUBWyUPtD3J7gg6P97uRS_THDAUHMo2UYVhlnu9PV8SvbvjGj3OeaaH7ZbzWQCYKbqsLZAZ2mnJlFhTMghbaC2s_MND1zlRm7w9btmihxVW714NUbH8UAwSvrtIYYQ0itevZ59TLiAXprjmjkhiFkrhdX4bUje4uNEbLYawkZI-1o82IExW9D8kCYpOWOZdWTCLgmaE2wXcf-DTCV-9vDWRAdX1YmP4JbRsc",
"cache-control: no-cache",
"content-type: multipart/form-data; boundary=----WebKitFormBoundary7MA4YWxkTrZu0gW",
"postman-token: 2ec7a2c8-3489-812d-4638-ebb7dc62aeb1"
),
我有 1 个使用 Vue 组件生成的个人访问令牌
我已经检查过我将令牌有效期设置为 1 年,这反映在数据库中。
我的AuthServiceProvider.php
Passport::routes();
// TODO MAKE THEM LAST A LONG TIME
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::tokensCan([
'api-access' => 'Access Complete API',
]);
我的RouteServiceProvider.php(map函数中调用了mapApiRoutes)
protected function mapApiRoutes()
{
Route::group([
'namespace' => $this->namespace,
'prefix' => 'api',
], function ($router) {
require base_path('routes/api.php');
});
}
我的Kernel.php路由中间件
protected $routeMiddleware = [
'auth' => \Illuminate\Auth\Middleware\Authenticate::class,
'auth.basic' => \Illuminate\Auth\Middleware\AuthenticateWithBasicAuth::class,
'bindings' => \Illuminate\Routing\Middleware\SubstituteBindings::class,
'can' => \Illuminate\Auth\Middleware\Authorize::class,
'guest' => \App\Http\Middleware\RedirectIfAuthenticated::class,
'throttle' => \Illuminate\Routing\Middleware\ThrottleRequests::class,
];
-- 编辑 -- 经过更多研究
我正在使用 postman 来测试我的 api 身份验证,每次尝试都会得到 401。我已经尝试过 Personal Access Client 和 Password Grant Client,两者都有同样的问题。在查看了它们之后,我意识到它们都使用 Authorization Bearer [token] 格式。
所以我开始在 Passport 源中的各种文件中注销。
在TokenGuard.php
public function user(Request $request) {
Log::info('TokenGuard: '. $request);
if ($request->bearerToken()) {
return $this->authenticateViaBearerToken($request);
} elseif ($request->cookie(Passport::cookie())) {
return $this->authenticateViaCookie($request);
}
}
日志如下所示:
[2017-08-10 20:50:20] local.INFO: TokenGuard 93: GET /api/user HTTP/1.1
Accept: application/json
Accept-Encoding: gzip, deflate
Cache-Control: no-cache
Connection: keep-alive
Content-Type: application/json
Host: url.com:8888
Postman-Token: 66707fe5-8f6e-4920-948b-2804a76d4a65
User-Agent: PostmanRuntime/6.2.5
[2017-08-10 20:50:20] local.INFO: TokenGuard 93: GET /api/user HTTP/1.1
Accept: application/json
Accept-Encoding: gzip, deflate
Cache-Control: no-cache
Connection: keep-alive
Content-Type: application/json
Host: url.com:8888
Postman-Token: 66707fe5-8f6e-4920-948b-2804a76d4a65
User-Agent: PostmanRuntime/6.2.5
缺少的是请求的 Bearer [token] 部分。 TokenGuard 代码块是 运行 和 if/else。这就是我认为失败发生的地方。
它不应该也被注销吗?由于 Bearer Token 丢失 If/Else 失败,因此 return 401 是有意义的。
为什么我的 Token 会被从请求中剥离。
将此添加到项目 public 目录下的 .htaccess
文件中:
RewriteEngine on
RewriteCond %{HTTP:Authorization} ^(.*)
RewriteRule .* - [e=HTTP_AUTHORIZATION:%1]