skip to Main Content

I’m trying to do OAuth2 authorization on Laravel 10 using the API. Registration and authorization works, but I can’t get a token either during registration or authorization. It would be correct to say that I am not receiving the token in the form in which it can be used in further requests. See 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."
}

I expect to see the token in this form:

enter image description here

Versions

  • PHP 8.1.21
  • Laravel Framework 10.14.1
  • Laravel Passport 11.8.8

Some general information

Before the test, the command to create a personal access client was executed:

php artisan passport:client --personal --no-interaction

Command output:

Personal access client created successfully.
Client ID: 16
Client secret: KjpvwyB1XMZTfh8aFZzrSJZrb3di83JZsj6ZvRud

After that in the database, a row was created in the oauth_clients table:
enter image description here

and in oauth_personal_access_clients table:
enter image description here

Then I added the id and secret key to the .env file.

.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 AppHttpControllersApi;

use AppHttpRequestsApiLoginRequest;
use AppHttpRequestsApiRegisterRequest;
use AppHttpResourcesUserResource;
use AppModelsUser;
use IlluminateHttpJsonResponse;
use IlluminateSupportFacadesAuth;

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 AppHttpControllersApi;

use AppHttpControllersController;
use IlluminateHttpJsonResponse;

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);
    }
}

I was advised to add the api_token field in the users table, since in the file config/auth.php the guards.api.provider parameter specifies users. However, this did not help solve the problem, which is obvious. I tried to completely repeat the algorithm of actions described in this article.

2

Answers


  1. please check your User Models,
    user model should have HasApiTokens

    Login or Signup to reply.
  2. First check in your User model namespace should like this if you need direct token

    use LaravelPassportHasApiTokens;
    

    Not

    use LaravelSanctumHasApiTokens;
    

    If you need a robust OAuth2 implementation with features like authorization codes, token refreshing, and third-party application integration, go for Passport (use LaravelPassportHasApiTokens).

    If your application is relatively simple and you want quick, stateless API authentication, especially for SPAs and mobile apps, Sanctum (use LaravelSanctumHasApiTokens) might be the better choice. And it can be access by

    $access_toekn = $user->createToken('X-Soft Personal Access Client')->accessToken;
    $token = $access_toekn->token;
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search