Search code examples
mongodblaravel-5laravel-passport

Laravel 5.4 mongodb passport access token Unauthenticated


I've built an example Laravel project using mongodb (Jenssegers Mongodb) and I use passport in Laravel 5.4 follow by this document.

Everything work fine until I took an access token to Postman for test, now take a look at my api.php route

Route::middleware('auth:api')->get('/user', function (Request $request) {
    return $request->user();
});

In postman, I setup two headers that are Accept: application/json and Authorization: Bearer $TOKEN and I'm very sure that my access token is not the copy missing fault but still getting error.

{
    "error": "Unauthenticated."
}

Things I've tried

I have overwrite default id field in model User.php

use Authenticatable, Authorizable, CanResetPassword, Notifiable, HasApiTokens;

protected $collection = 'users';
protected $fillable = ['username', 'email', 'password', 'name'];
protected $primaryKey = '_id';

I also modify the token expiration time in AuthserviceProvider.php like so

public function boot()
{
    $this->registerPolicies();

    Passport::routes();
    Passport::tokensExpireIn(Carbon::now()->addYears(20));//You can also use addDays(10)
    Passport::refreshTokensExpireIn(Carbon::now()->addYears(20));//You can also use addDays(10)
    Passport::pruneRevokedTokens(); //basic garbage collector

    Passport::tokensCan([
        'conference' => 'Access your conference information'
    ]);
}

And some other ways but still not work.

UPDATE for debug infomation

When I add try catch in to public/index.php, an error apperead

League\OAuth2\Server\Exception\OAuthServerException: The resource owner or authorization server denied the request. in /data/www/public_html/xxxx/vendor/league/oauth2-server/src/Exception/OAuthServerException.php:165
Stack trace:
#0 /data/www/public_html/xxxx/vendor/league/oauth2-server/src/AuthorizationValidators/BearerTokenValidator.php(66): League\OAuth2\Server\Exception\OAuthServerException::accessDenied('Access token ha...')
#1 /data/www/public_html/xxxx/vendor/league/oauth2-server/src/ResourceServer.php(82): League\OAuth2\Server\AuthorizationValidators\BearerTokenValidator->validateAuthorization(Object(Zend\Diactoros\ServerRequest))
......

When I check file vendor\league\oauth2-server\src\AuthorizationValidators\BearerTokenValidator.php at line 66. Seems my access token has been revoked, but in my database revoked column still false, and this access token is brand new, I just created in few minutes ago.

if ($this->accessTokenRepository->isAccessTokenRevoked($token->getClaim('jti'))) {
    throw OAuthServerException::accessDenied('Access token has been revoked');
}

Any idea?


Solution

  • After few hours of digging deep in to vendor\league\oauth2-server\src\AuthorizationValidators\BearerTokenValidator.php I was found a solution.

    The problem is in file vendor\laravel\passport\src\TokenRepository.php at function public function find($id) line 27

    public function find($id)
    {
        return Token::find($id);
    }
    

    Because I use Mobodb and this function is use use Jenssegers\Mongodb\Eloquent\Model and it search for _id instead of id. So, just need to make change find function like this.

    public function find($id)
    {
        return Token::where('id', $id)->first();
    }
    

    Although modify vendor file is not recommend, but in this case I have to do that, hopefully in next version, author of Laravel passport will release a passport support mongoDB.

    Hope this help someone.