php Laravel 10 Passport返回一个token对象,但不是token

8wtpewkr  于 2023-10-15  发布在  PHP
关注(0)|答案(2)|浏览(137)

我正在尝试使用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."
}

我希望看到这种形式的token:

版本号

  • PHP 8.1.21
  • Laravel Framework 10.14.1
  • Laravel Passport 11.8.8

一般信息

在测试之前,执行了创建个人访问客户端的命令:

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

config/auth.php

return [
    'guards' => [
        'web' => [
            'driver' => 'session',
            'provider' => 'users',
        ],
        'api' => [
            'driver' => 'passport',
            'provider' => 'users',
            'hash' => true,
        ],
    ],
];

routes/api.php

Route::post('register', [AuthController::class, 'register']);
Route::post('login', [AuthController::class, 'login']);

app/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,
        ]));
    }
}

app/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字段,因为在文件js/auth.php中,guards.api.provider参数指定users。然而,这并没有帮助解决问题,这是显而易见的。我试图完全重复this article中描述的操作算法。

k3fezbri

k3fezbri1#

请检查您的用户模型,用户模型应该有HasApiTokens

7gyucuyw

7gyucuyw2#

首先检查用户模型命名空间,如果您需要直接令牌,则应该如下所示

use Laravel\Passport\HasApiTokens;

use Laravel\Sanctum\HasApiTokens;

如果您需要一个健壮的OAuth2实现,包括授权码、令牌刷新和第三方应用程序集成等功能,请选择Passport(use Laravel\Passport\HasApiTokens)。
如果您的应用程序相对简单,并且您希望快速、无状态的API身份验证,特别是对于SPA和移动的应用程序,Sanctum(use Laravel\Sanctum\HasApiTokens)可能是更好的选择。它可以通过

$access_toekn = $user->createToken('X-Soft Personal Access Client')->accessToken;
$token = $access_toekn->token;

相关问题