我正在尝试使用 API 在 Laravel 10 上进行 OAuth2 授权。注册和授权有效,但在注册或授权期间我无法获得令牌。正确的说法是,我没有收到可在进一步请求中使用的令牌。参见
data.access_token
:
{
"success": true,
"data": {
"id": 1,
"name": "Schizo",
"email": "********@gmail.com",
"access_token": {
"name": "DesktopClient",
"abilities": [
"*"
],
"expires_at": null,
"tokenable_id": 1,
"tokenable_type": "App\\Models\\User",
"updated_at": "2023-07-08T16:22:30.000000Z",
"created_at": "2023-07-08T16:22:30.000000Z",
"id": 2
}
},
"message": "User login successfully."
}
我希望看到这种形式的令牌:
测试前执行创建个人访问客户端的命令:
php artisan passport:client --personal --no-interaction
命令输出:
Personal access client created successfully.
Client ID: 16
Client secret: KjpvwyB1XMZTfh8aFZzrSJZrb3di83JZsj6ZvRud
之后在数据库中,在
oauth_clients
表中创建了一行:
和
oauth_personal_access_clients
表中:
然后我将 id 和密钥添加到 .env 文件中。
.env
PASSPORT_PERSONAL_ACCESS_CLIENT_ID=16
PASSPORT_PERSONAL_ACCESS_CLIENT_SECRET=KjpvwyB1XMZTfh8aFZzrSJZrb3di83JZsj6ZvRud
配置/auth.php
return [
'guards' => [
'web' => [
'driver' => 'session',
'provider' => 'users',
],
'api' => [
'driver' => 'passport',
'provider' => 'users',
'hash' => true,
],
],
];
路线/api.php
Route::post('register', [AuthController::class, 'register']);
Route::post('login', [AuthController::class, 'login']);
应用程序/Http/Controllers/AuthController.php
namespace App\Http\Controllers\Api;
use App\Http\Requests\ApiLoginRequest;
use App\Http\Requests\ApiRegisterRequest;
use App\Http\Resources\UserResource;
use App\Models\User;
use Illuminate\Http\JsonResponse;
use Illuminate\Support\Facades\Auth;
class AuthController extends ApiController
{
/**
* Performs user registration.
*
* @param ApiRegisterRequest $apiRegisterRequest
* @return JsonResponse
*/
public function register(ApiRegisterRequest $apiRegisterRequest): JsonResponse
{
$input = $apiRegisterRequest->validated();
$input['password'] = bcrypt($input['password']);
return $this->sendResponse(
$this->getUserResourceWithAccessToken(User::create($input)),
'User register successfully.'
);
}
/**
* Performs user authorization.
*
* @param ApiLoginRequest $apiLoginRequest
* @return JsonResponse
*/
public function login(ApiLoginRequest $apiLoginRequest): JsonResponse
{
if (!Auth::attempt($apiLoginRequest->validated())) {
return $this->sendError('Unauthorised.', [
'error' => 'Unauthorised.'
]);
} else {
return $this->sendResponse(
$this->getUserResourceWithAccessToken(Auth::user()),
'User login successfully.'
);
}
}
/**
* Returns compressed user data with an access token.
*
* @param User $user
* @return UserResource
*/
private function getUserResourceWithAccessToken(User $user): UserResource
{
return new UserResource(array_merge($user->getAttributes(), [
'access_token' => $user->createToken('X-Soft Personal Access Client')->accessToken,
]));
}
}
应用程序/Http/Controllers/ApiController.php
namespace App\Http\Controllers\Api;
use App\Http\Controllers\Controller;
use Illuminate\Http\JsonResponse;
class ApiController extends Controller
{
/**
* Success response method.
*
* @param mixed $result
* @param string $message
* @return JsonResponse
*/
public function sendResponse(mixed $result, string $message): JsonResponse
{
return response()->json([
'success' => true,
'data' => $result,
'message' => $message,
]);
}
/**
* Return error response.
*
* @param string $error
* @param array $errorMessages
* @param int $code
* @return JsonResponse
*/
public function sendError(string $error, array $errorMessages = [], int $code = 404): JsonResponse
{
$response = [
'success' => false,
'message' => $error,
];
if (!empty($errorMessages)) {
$response['data'] = $errorMessages;
}
return response()->json($response, $code);
}
}
我被建议在 users 表中添加
api_token
字段,因为在文件 config/auth.php 中 guards.api.provider
参数指定 users
。然而,这并没有帮助解决问题,这是显而易见的。我尝试完全重复本文中描述的操作算法。
请检查您的用户模型, 用户模型应该有 HasApiTokens