laravel 6 护照中出现未经授权的 401 错误
Unauthorized 401 error in laravel 6 passport
我正在尝试使用 laravel 通行证来验证用户。我遵循了 laravel 护照文件中的每一步。但是当我访问受 'auth:api' 中间件保护的路由时它显示错误。我已经在互联网上搜索过,但到目前为止,任何答案都不起作用。请查看代码,以及我在下面尝试过的内容。
使用的技术
- Laravel 6
- Laravel护照
- Vue 2
- Axios
目前已尝试:
- 在
AuthServiceProvider
中将 Passport::routes();
更改为 Passport::routes(null, ['prefix' => 'api/oauth', 'middleware' => ['auth:api', 'web', 'auth']]);
。也试过Passport::routes(null, ['prefix' => 'api/oauth');
- 已尝试 运行
php artisan cache:clear
routes/api.php
Route::middleware('auth:api')->group(function() {
Route::get('user', function() {
return request()->user();
});
Route::get('posts', 'PostController@index')->name('posts');
Route::post('posts/store', 'PostController@store')->name('posts.store');
Route::get('posts/{id}/show')->name('posts.show');
Route::get('users/{id}/show')->name('users.show');
});
Axios
mounted() {
axios.get('/api/posts')
.then(res => this.posts = res.data).catch(error => console.log('Unable to fetch posts.'))
}
错误
Headers:
如果您需要一些我的 post 中未指明的详细信息,请告诉我。
设置
- 运行
composer require laravel/passport:9
用于安装。
- 运行
php artisan migrate
表格。
- 运行
php artisan passport:install
生成加密密钥。
- 在
User
模型中添加了 Laravel\Passport\HasApiTokens
特征。
- 在
AuthServiceProvider
中添加了 Passport::routes();
。
- 将
guard
的 api
driver 更改为 config/auth.php
中的 passport
。
完整源代码:
如果您使用 Api/oauth 前缀并添加 auth:api 中间件,那么您需要通过 Bearer 令牌进行身份验证。
可能是您遇到了与 csrf 令牌相关的问题,请尝试在下方禁用它。
Passport::ignoreCsrfToken(true);
您应该将令牌持有者添加到您的 ajax 请求中。登录成功即可领取。
// laravel
use Illuminate\Support\Facades\Auth;
use App\Models\User;
public function login()
{
$credentials = request(['email', 'password']);
$user = User::where('email', $credentials['email'])->first();
if (!$user || !$token = Auth::attempt($credentials)) {
return response()->json(['success'=> false, 'error' => 'неверный логин или пароль', 'cr' => $credentials], 422);
}
return $this->respondWithToken($token);
}
// vue login
async function login(email, password) {
try {
const response = await axios.post('/auth/login', {email, password});
const token = response.data.token;
// some func to store token, I am using vuex mutations for this
storeToken(token);
}
catch(error) {
console.error(error);
}
};
// vue regular function
async function changePassword(newPassword) {
// get token from global storage, with vuex it will be like store.state.auth.token
const token = getToken();
await axios.post('/user/changePassword', {newPassword}, headers: { Authorization: `Bearer ${token}`});
}
我认为您应该按照以下步骤检查您的代码。
步骤 1:User
模型必须使用 HasApiTokens
...
class User extends Authenticatable
{
use HasApiTokens, Notifiable;
}
步骤 2:Passport::routes
方法在 AuthServiceProvider
的启动方法中
class AuthServiceProvider extends ServiceProvider
{
...
public function boot()
{
$this->registerPolicies();
Passport::routes();
}
}
第 3 步:在你的 config/auth.php
配置文件中,你应该将 api 身份验证保护的 driver 选项设置为 passport
'guards' => [
'api' => [
'driver' => 'passport',
'provider' => 'users',
],
],
步骤 4(可选):
如果您想从您的 JavaScript 应用程序中使用您的 API,您需要手动向该应用程序发送一个访问令牌,并将它与每个请求一起传递给您的应用程序。但是,Passport
包含一个可以为您处理此问题的中间件。您需要做的就是将 CreateFreshApiToken
中间件添加到 app/Http/Kernel.php
文件中的 web 中间件组:
'web' => [
// Other middleware...
\Laravel\Passport\Http\Middleware\CreateFreshApiToken::class,
],
!您应该确保 CreateFreshApiToken
中间件是中间件堆栈中列出的最后一个中间件。
编辑 (2021/10/17):
您应该尝试将 auth 中间件添加到 Kernel.php
的 $middlewareGroups
protected $middlewareGroups = [
...
'api' => [
'throttle:60,1',
\Illuminate\Routing\Middleware\SubstituteBindings::class,
'auth:api', //Need to add
],
];
编辑 (2021/10/25):
我下载了你的代码并调试了它。当你调试它时,你会得到如下结果:
Header JWT 对 JSON 结构无效。 Laravel Passport
库与您的系统似乎不兼容。您应该检查您的系统版本(PHP、Laravel 等)。我会继续调查。如果您有任何新的信息,请告诉我
编辑 (2021/11/02):
Update your laravel/framework dependency to ^6.0 in your composer.json file. If installed, update your laravel/passport dependency to ^9.3.2 in your composer.json file.
https://laravel.com/docs/6.x/upgrade#updating-dependencies
根据Laravel 6.x
文档,Laravel Passport 的版本来自 9.3.2。请试试这个版本。
您忘记了 运行 php artisan passport:keys
...so there may be no RSA key-pair available, which is crucial. Clients usually can be added with: php artisan passport:client
. And generally speaking, there is no default recipe for debugging Laravel middleware ...there only is xdebug
。
我正在尝试使用 laravel 通行证来验证用户。我遵循了 laravel 护照文件中的每一步。但是当我访问受 'auth:api' 中间件保护的路由时它显示错误。我已经在互联网上搜索过,但到目前为止,任何答案都不起作用。请查看代码,以及我在下面尝试过的内容。
使用的技术
- Laravel 6
- Laravel护照
- Vue 2
- Axios
目前已尝试:
- 在
AuthServiceProvider
中将Passport::routes();
更改为Passport::routes(null, ['prefix' => 'api/oauth', 'middleware' => ['auth:api', 'web', 'auth']]);
。也试过Passport::routes(null, ['prefix' => 'api/oauth');
- 已尝试 运行
php artisan cache:clear
routes/api.php
Route::middleware('auth:api')->group(function() {
Route::get('user', function() {
return request()->user();
});
Route::get('posts', 'PostController@index')->name('posts');
Route::post('posts/store', 'PostController@store')->name('posts.store');
Route::get('posts/{id}/show')->name('posts.show');
Route::get('users/{id}/show')->name('users.show');
});
Axios
mounted() {
axios.get('/api/posts')
.then(res => this.posts = res.data).catch(error => console.log('Unable to fetch posts.'))
}
错误
Headers:
如果您需要一些我的 post 中未指明的详细信息,请告诉我。
设置
- 运行
composer require laravel/passport:9
用于安装。 - 运行
php artisan migrate
表格。 - 运行
php artisan passport:install
生成加密密钥。 - 在
User
模型中添加了Laravel\Passport\HasApiTokens
特征。 - 在
AuthServiceProvider
中添加了Passport::routes();
。 - 将
guard
的api
driver 更改为config/auth.php
中的passport
。
完整源代码:
如果您使用 Api/oauth 前缀并添加 auth:api 中间件,那么您需要通过 Bearer 令牌进行身份验证。
可能是您遇到了与 csrf 令牌相关的问题,请尝试在下方禁用它。
Passport::ignoreCsrfToken(true);
您应该将令牌持有者添加到您的 ajax 请求中。登录成功即可领取。
// laravel
use Illuminate\Support\Facades\Auth;
use App\Models\User;
public function login()
{
$credentials = request(['email', 'password']);
$user = User::where('email', $credentials['email'])->first();
if (!$user || !$token = Auth::attempt($credentials)) {
return response()->json(['success'=> false, 'error' => 'неверный логин или пароль', 'cr' => $credentials], 422);
}
return $this->respondWithToken($token);
}
// vue login
async function login(email, password) {
try {
const response = await axios.post('/auth/login', {email, password});
const token = response.data.token;
// some func to store token, I am using vuex mutations for this
storeToken(token);
}
catch(error) {
console.error(error);
}
};
// vue regular function
async function changePassword(newPassword) {
// get token from global storage, with vuex it will be like store.state.auth.token
const token = getToken();
await axios.post('/user/changePassword', {newPassword}, headers: { Authorization: `Bearer ${token}`});
}
我认为您应该按照以下步骤检查您的代码。
步骤 1:User
模型必须使用 HasApiTokens
...
class User extends Authenticatable
{
use HasApiTokens, Notifiable;
}
步骤 2:Passport::routes
方法在 AuthServiceProvider
class AuthServiceProvider extends ServiceProvider
{
...
public function boot()
{
$this->registerPolicies();
Passport::routes();
}
}
第 3 步:在你的 config/auth.php
配置文件中,你应该将 api 身份验证保护的 driver 选项设置为 passport
'guards' => [
'api' => [
'driver' => 'passport',
'provider' => 'users',
],
],
步骤 4(可选):
如果您想从您的 JavaScript 应用程序中使用您的 API,您需要手动向该应用程序发送一个访问令牌,并将它与每个请求一起传递给您的应用程序。但是,Passport
包含一个可以为您处理此问题的中间件。您需要做的就是将 CreateFreshApiToken
中间件添加到 app/Http/Kernel.php
文件中的 web 中间件组:
'web' => [
// Other middleware...
\Laravel\Passport\Http\Middleware\CreateFreshApiToken::class,
],
!您应该确保 CreateFreshApiToken
中间件是中间件堆栈中列出的最后一个中间件。
编辑 (2021/10/17):
您应该尝试将 auth 中间件添加到 Kernel.php
$middlewareGroups
protected $middlewareGroups = [
...
'api' => [
'throttle:60,1',
\Illuminate\Routing\Middleware\SubstituteBindings::class,
'auth:api', //Need to add
],
];
编辑 (2021/10/25):
我下载了你的代码并调试了它。当你调试它时,你会得到如下结果:
Header JWT 对 JSON 结构无效。 Laravel Passport
库与您的系统似乎不兼容。您应该检查您的系统版本(PHP、Laravel 等)。我会继续调查。如果您有任何新的信息,请告诉我
编辑 (2021/11/02):
Update your laravel/framework dependency to ^6.0 in your composer.json file. If installed, update your laravel/passport dependency to ^9.3.2 in your composer.json file.
https://laravel.com/docs/6.x/upgrade#updating-dependencies
根据Laravel 6.x
文档,Laravel Passport 的版本来自 9.3.2。请试试这个版本。
您忘记了 运行 php artisan passport:keys
...so there may be no RSA key-pair available, which is crucial. Clients usually can be added with: php artisan passport:client
. And generally speaking, there is no default recipe for debugging Laravel middleware ...there only is xdebug
。