Adam
Adam

Reputation: 29059

How to only allow Bearer token in API authentication?

When using $this->middleware('auth:auth') the user token can be passed as query string, request payload or bearer token: https://laravel.com/docs/5.8/api-authentication#passing-tokens-in-requests

I want to only allow authentication by bearer token. This means I don't want to allow authentication by query string or post request.

I tried to solve it by adding a middleware which just removes the api_token

public function handle($request, Closure $next)
{
    $request->request->set('api_token', null);
    return $next($request);
}

but no matter what I do

Route::group(['middleware' => ['auth:api', 'remove-api-token'],

or

Route::group(['middleware' => ['remove-api-token', 'auth:api'],

will always trigger auth:api first. So my approach does not work.

Any ideas how to deny GET/POST authentication for auth:api only?

Upvotes: 2

Views: 1690

Answers (1)

Remul
Remul

Reputation: 8252

One option would be to extend the existing tokenGuard and overwrite the getTokenForRequest() method to only accept the bearer token:

Create a new Guard:

"app\Services\Auth\BearerTokenGuard.php"

<?php

namespace App\Services\Auth;

use Illuminate\Auth\TokenGuard;

class BearerTokenGuard extends TokenGuard
{
    /**
     * Get the token for the current request.
     *
     * @return string
     */
    public function getTokenForRequest()
    {
        return $this->request->bearerToken();
    }
}

Define your new Guard within a service provider:

"app\Providers\AuthServiceProvider.php"

use App\Services\Auth\BearerTokenGuard;

/**
 * Register any authentication / authorization services.
 *
 * @return void
 */
public function boot()
{
    Auth::extend('bearerToken', function ($app, $name, array $config) {
        return new BearerTokenGuard(Auth::createUserProvider($config['provider']), $app['request']);
    });
}

add your new guard driver to the guards config:

"config\auth.php"

'guards' => [
    'api' => [
        'driver' => 'bearerToken',
        'provider' => 'users',
        'hash' => false,
    ],
],

I have not tested this, but it should work, although it might need some modifications.

Upvotes: 2

Related Questions