Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Passport 401 Unauthenticated. #839

Closed
agorenja opened this issue Oct 9, 2018 · 20 comments
Closed

Passport 401 Unauthenticated. #839

agorenja opened this issue Oct 9, 2018 · 20 comments

Comments

@agorenja
Copy link

agorenja commented Oct 9, 2018

Laravel: 5.6.27
Passport: 7.0.1
Passport work ok with personal access token, but not with OAuth clients.

I found bug in vendor/laravel/passport/src/Guards/TokenGuard.php in protected function authenticateViaBearerToken($request).
$psr->getAttribute('oauth_user_id') always return null, so I added this code for quick fix, and it's working now:

Line: 118

$clientId = $psr->getAttribute('oauth_client_id');       
if(!$user) {
    $clientId = $psr->getAttribute('oauth_client_id');
   $user = $this->provider->retrieveById(optional(\Laravel\Passport\Client::find($clientId))>user_id);
  }
@xutl
Copy link

xutl commented Oct 10, 2018

AuthServiceProvider file add Passport::$ignoreCsrfToken = true;

@agorenja
Copy link
Author

AuthServiceProvider file add Passport::$ignoreCsrfToken = true;

Tried this, but it's not working.

@JoaoPortella
Copy link

Same error!
Laravel v5.7.9
Passport v7.0.2

Work fine in all my routes, but not with GET oauth/clients or any other Client oauth routes

@xutl
Copy link

xutl commented Oct 11, 2018

@agorenja Make sure of your Controller

public function __construct()
    {
        $this->middleware('auth:api');
    }

$this->middleware('auth'); it is wrong

@agorenja
Copy link
Author

@xutl I get the same error (oauth_user_id -> null) with /oauth/clients

@driesvints
Copy link
Member

Ok so it took me a while to understand this myself. The api routes for managing the oauth clients cannot be used by authenticating with a Bearer token. It can only be accessed when a user is authenticated though a web app. The reason for this is that the routes are protected by the web and auth middleware and not the api and auth:api middleware as you'd expect. The exact reason for this is that you'd normally only access these routes from an authenticated state in a Laravel application. When this happens a cookie for the authed user is set and the routes can be accessed by using axios for example (see the docs).

I do agree that the docs are not clear on this and that it's pretty confusing. I'll send in a PR later to make sure they're more clear.

A better way would be to make it an actual JSON API with Bearer authentication. We could combine this with the https://laravel.com/docs/5.7/passport#consuming-your-api-with-javascript functionality in other apps. I'll try to see if this can be updated in a future Passport version. That way the client api endpoints could be consumed as an actual api.

Anyway, hope this response helps others who have been searching for a solution.

@JoaoPortella
Copy link

@driesvints , thanks for the explanation, now it's all clearer.
But I'm a bit disappointed. I use only the passport in my App, so I would like to see this feature available as soon as possible.
Again, thank you for clarifying the issue.

@natepisarski
Copy link

By the way - I had this problem just after configuring Passport. The solution in my case was a simple

php artisan optimize:clear

@shawnfromportland
Copy link

I was able to resolve this error that dozens or hundreds of people report online, but none of the existing solutions worked for me, except for the following.
using Laravel 5.8, following docs to set up Passport.

In my case, although I was including the csrf token in a meta tag, it was not being picked up as the Passport documentation states that laravel will by default. from the docs (https://laravel.com/docs/5.8/passport#consuming-your-api-with-javascript):

" the default Laravel JavaScript scaffolding instructs Axios to always send the X-CSRF-TOKEN and X-Requested-With headers. "

and then the example is provided:

// In your application layout...
<meta name="csrf-token" content="{{ csrf_token() }}">

// Laravel's JavaScript scaffolding...
window.axios.defaults.headers.common = {
    'X-Requested-With': 'XMLHttpRequest',
};

Well that would be great if it worked that way by default as the docs state, but in my case I had to explicitly set the axios default to include the contents of said csrf-token meta tag before making the axios request. like this:

window.axios.defaults.headers.common = {
						'X-Requested-With': 'XMLHttpRequest',
						'X-CSRF-TOKEN' : document.querySelector('meta[name="csrf-token"]').getAttribute('content')
				};

In my case, this was the only thing that allowed me to get past the 401 unauthorized error, which seems to indicate either:
A) something in my project's configuration has altered the default behavior of axios requests by not setting them automatically include the csrf-token based on the meta tag if present or
B) the docs are inaccurate on this one point, and in the present version of Laravel and Passport that is not the default behavior as stated.

@rbourtoutian
Copy link

SOLVED: I am pretty sure you followed all the configurations of Laravel Passport and you have a functioning login page. Your only issue is that when you try hitting an auth:api protected route you get this 401 error.

MY PROBLEM was that I wasn't sending the bearer token with the request to the route. Now, this might be a BAD way to solve this problem, but it is a start and I am gonna read up on this and find a BETTER way, but well, I started adding this (axios.defaults.headers.common['Authorization'] = 'Bearer ' + localStorage.getItem('token')) to all the actions in the modules of my store wherever an authenticated user should hit the route and the problem was solved.

Keep in mind that you need to save your token (or access_token however you named it) in your localStorage for this particular case to work.

@mhfuad
Copy link

mhfuad commented Nov 21, 2019

If you are using client credentials to generate your access_token.

  1. Add to the routeMiddleware in \App\Http\Kernel.php 'client_credentials' => \Laravel\Passport\Http\Middleware\CheckClientCredentials::class,
  2. Use 'client_credentials' middleware in your route too.
    like this
    Route::group(['middleware' => 'client_credentials'], function () {
    //your route
    });

@edsel77
Copy link

edsel77 commented Jan 12, 2020

By the way - I had this problem just after configuring Passport. The solution in my case was a simple

php artisan optimize:clear

thanks for this

@mhfuad
Copy link

mhfuad commented Jan 18, 2020 via email

@soheilyou
Copy link

I did like this and the problem is gone!

php artisan optimize:clear
php artisan migrate:rollback
php artisan passport:install --forced

@sgflores
Copy link

If you are using client credentials to generate your access_token.

  1. Add to the routeMiddleware in \App\Http\Kernel.php 'client_credentials' => \Laravel\Passport\Http\Middleware\CheckClientCredentials::class,
  2. Use 'client_credentials' middleware in your route too.
    like this
    Route::group(['middleware' => 'client_credentials'], function () {
    //your route
    });

This works with me.

@krishnavala
Copy link

I did like this and the problem is gone!

php artisan optimize:clear
php artisan migrate:rollback
php artisan passport:install --forced

This is work for me thank you.

@sbarbat
Copy link

sbarbat commented May 2, 2020

I added the route on my route/api.php

Route::post('oauth/token', '\Laravel\Passport\Http\Controllers\AccessTokenController@issueToken')
    ->name('api.passport.token');

@aadriantech
Copy link

aadriantech commented May 27, 2020

If you are using client credentials to generate your access_token.

  1. Add to the routeMiddleware in \App\Http\Kernel.php 'client_credentials' => \Laravel\Passport\Http\Middleware\CheckClientCredentials::class,
  2. Use 'client_credentials' middleware in your route too.
    like this
    Route::group(['middleware' => 'client_credentials'], function () {
    //your route
    });

This worked for me too! When you generate access_tokens via client credentials, eg: email and password

Set middleware to client_credentials and remove auth:api
Route::group(['middleware' => 'client_credentials'], function () {
// routes
}

// Add this to Http/Kernel.php $routeMiddleware array
/* other middlewares ... */
'client_credentials' => \Laravel\Passport\Http\Middleware\CheckClientCredentials::class,

and use it as Authorization Bearer value

@sam-mak-dream
Copy link

@aadriantech Awesome. Life-saving solution. Worked for me
I seen lots and lots of stuff but never find this.
Can you tell me where did you find this?

@riyaz7us
Copy link

riyaz7us commented Jun 27, 2020

None of these solutions worked (using laravel 7.0 and passport 9.2). Tried apache authorization header modification, composer dump-autoload, optimize:clear, passport:keys --forced, passport:install --forced, Passport::withoutCookieSerialization(). Last thing I saw was this error logged:

[2020-06-27 12:12:23] local.ERROR: The resource owner or authorization server denied the request. {"exception":"[object] (League\\OAuth2\\Server\\Exception\\OAuthServerException(code: 9): The resource owner or authorization server denied the request. at C:\\laragon\\www\\edukit\\vendor\\league\\oauth2-server\\src\\Exception\\OAuthServerException.php:243)
[stacktrace]
.....

The error faded away when I used this method, but the problem persisted:

If you are using client credentials to generate your access_token.

1. Add to the routeMiddleware in \App\Http\Kernel.php 'client_credentials' => \Laravel\Passport\Http\Middleware\CheckClientCredentials::class,

2. Use 'client_credentials' middleware in your route too.
   like this
   Route::group(['middleware' => 'client_credentials'], function () {
   //your route
   });

Later, I realized that the rest client also appended my user name and password (I wasn't using postman for speed issue in my pc).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests