I've been working in this application for several years and while doing some updates my passport authentication broke. I update from passport 7.2 to 7.5 and it broke. I then updated to passport 8.5 and it still doesn't work.
I am getting the 401 {error: "Unauthenticated."} error.
I am using
Laravel 7.28.1
Passport 8.5.0
Laravel Valet
PHP 7.3
I am attempting to consume my own api and I've followed every solution I found on the internet, but no dice. I can access the routes using postman with an access token and if I move the route outside of the auth:api middleware, but I want to access the routes within the auth:api
Here is my current config.
AuthServiceProvider.php
public function boot()
{
Passport::routes();
}
protected $middlewareGroups = [
'web' => [
\App\Http\Middleware\EncryptCookies::class,
... other middleware
\Laravel\Passport\Http\Middleware\CreateFreshApiToken::class,
],
'api' => [
'throttle:60,1',
'bindings',
],
];
In auth.php
'guards' => [
'web' => [
'driver' => 'session',
'provider' => 'users',
],
'api' => [
'driver' => 'passport',
'provider' => 'users',
'hash' => false,
],
]
]
bootstrap.js
window.axios = require('axios');
window.axios.defaults.headers.common = {
'X-CSRF-TOKEN' : document.querySelector('meta[name="csrf-token"]').getAttribute('content'),
'X-Requested-With': 'XMLHttpRequest'
};
in a component.vue file
axios.get('/api/users?page=' + page).then((response) => {
//
})
I've cleared configs and ran php artisan optimize:clear and about a dozen of other things that I can't thing of right now.
Any help would be appreciated.
I've encountered exactly this problem with Laravel 7 and Passport starting around the time of this question posted (early September 2020). I couldn't pin-point the exact cause of the issue, but had to freeze my dependencies to avoid the problem. While debugging it seemed to me it wasn't a direct issue with Laravel or Passport, but rather a sub-dependency.
Just upgraded to Laravel 8 and Passport v10.0.1 and now everything is back to normal.
Related
We have several Laravel applications that use Backpack for the admin panel. A developer wrote a package that used Single sign-on. We have removed this package as it was not working correctly. Once Composer was used to updating Laravel and remove the package, there are NO routes to deal with admin login. Our applications use Laravel 5.8/6 and Backpack 3.6/4.0.
I created another test application with Laravel 5.8 using Backpack 3.6, and the routes are available for login. As you can see, all the login routes are available.
If you look at the following image, you can see the login routes are all missing.
Is there a way to add the routes in again? Laravel Backpack is still installed, but I need to re-register the routes.
All the settings in the application are set to default. I have even made the default authentication guard in config/auth.php to Backpack.
config/auth.php
'defaults' => [
'guard' => 'backpack',
'passwords' => 'users',
],
'providers' => [
'users' => [
'driver' => 'eloquent',
'model' => App\Models\User::class,
],
],
config/backpack/base.php
'route_prefix' => 'admin',
'setup_auth_routes' => false,
'setup_dashboard_routes' => true,
'setup_my_account_routes' => true,
'user_model_fqn' => App\Models\BackpackUser::class,
'middleware_class' => [
App\Http\Middleware\CheckIfAdmin::class,
\Illuminate\Foundation\Http\Middleware\ConvertEmptyStringsToNull::class,
// \Backpack\Base\app\Http\Middleware\UseBackpackAuthGuardInsteadOfDefaultAuthGuard::class,
],
// Alias for that middleware
'middleware_key' => 'admin',
'authentication_column' => 'email',
'authentication_column_name' => 'Email',
'guard' => 'backpack',
'passwords' => 'backpack',
config/backpack/permissionmanager.php
'models' => [
'user' => App\Models\BackpackUser::class,
'permission' => Backpack\PermissionManager\app\Models\Permission::class,
'role' => Backpack\PermissionManager\app\Models\Role::class,
],
'allow_permission_create' => false,
'allow_permission_update' => false,
'allow_permission_delete' => false,
'allow_role_create' => true,
'allow_role_update' => true,
'allow_role_delete' => true,
'multiple_guards' => true,
app/Models/BackpackUser.php
class BackpackUser extends User
{
use CrudTrait;
use HasRoles;
use InheritsRelationsFromParentModel;
protected $table = 'users';
public function sendPasswordResetNotification($token)
{
$this->notify(new ResetPasswordNotification($token));
}
public function getEmailForPasswordReset()
{
return $this->email;
}
}
So pretty much standard settings. I cannot figure out why the routes are not registered and available. If you get to http://localhost/admin, I get redirected to http://localhost/admin/login, which gives a 404 error. Can anyone help?
You have to enable 'setup_auth_routes' => true in config/base.php. This will allow Backpack to use the standard routes. Then the second step is to use Auth::routes(); inside your routes/web.php
If you are missing some/all of the controllers or UIs then you can scaffold them:
Install laravel/ui part using composer require laravel/ui
Use php artisan ui vue --auth or php artisan ui bootstrap --auth or php artisan ui react --auth depending on what you use for the front-end.
I am trying to figure out to provide multiple ways of authentication for the API service within my Laravel app. The app is a SPA using Vue.js and uses the API route to render and present all the view components. Currently, I am using a JWT driver for the API guard within the application. However, I'd also like to offer my clients the ability to access the same API via OAuth and Laravel's personal API token. With that being said, how do I protect my resources with the Auth middleware where it can be accessed internally with a JWT or externally by a client with OAuth or an API Token.
Controller:
/**
* Create a new controller instance.
*
* #return void
*/
public function __construct()
{
// Make sure user is authenticated
$this->middleware('auth:api');
//$this->middleware('auth:oauth');
}
Auth Guards:
'guards' => [
'web' => [
'driver' => 'session',
'provider' => 'users',
],
'api' => [
'driver' => 'jwt',
'provider' => 'users',
],
'oauth' => [
'driver' => 'token',
'provider' => 'users',
]
],
If you want to be able allow multiple guards for your routes you can supply the different guards to the middleware call, like you have done already with the api guard, except you supply them as comma separated values:
$this->middleware('auth:api,oauth,web');
This will mean that if a user has been authenticated with one of the guards they will be able to access the route(s).
I'm using this package for "jwt-auth" for my Laravel backend project, here is the link for the package:
https://jwt-auth.readthedocs.io/en/develop/
I have 2 middleware that I put the names Tenant and JWT, when my user tries to log in to the app he must send the company code, so my middleware Tenant picks the information from the specific connection database client and all is working fine.
But when I use 2 middlewares together, he gives me an error that I don't have a user table. He is right because when I made a searching from the problem I found that the package executes a function before all my 2 middlewares that is this:
/**
* Get the currently authenticated user.
*
* #return \Illuminate\Contracts\Auth\Authenticatable|null
*/
public function user()
{
// MODIFICAÇÃO CUSTOMIZADA DA FUNÇÃO USER
if ($this->user !== null) {
return $this->user;
}
if ($this->jwt->setRequest($this->request)->getToken() &&
($payload = $this->jwt->check(true)) &&
$this->validateSubject()
) {
return $this->user = $this->provider->retrieveById($payload['sub']);
}
}
The problem was solved if I comment this line "return $this->user = $this->provider->retrieveById($payload['sub']);", but this is not a good practice. The main reason for this error is that this function is executed before my Tenant middleware that doesn't have a user table in the database that Tenant middleware tries to connect.
The file name is **JWT_GUARD.php in tymon\jwt-auth\src**, i'm think is something about my configuration that i must change in
config/auth.php from laravel
'defaults' => [
'guard' => 'api',
'passwords' => 'users',
],
And here:
'guards' => [
'web' => [
'driver' => 'session',
'provider' => 'users',
],
'api' => [
'driver' => 'jwt',
'provider' => 'users',
],
],
I comment on this part "return $this->user = $this->provider->retrieveById($payload['sub']);" and waiting for a better solution
I have situation about returning users from DB. In my controller I am trying it like below:
UPDATED:
NOTE: for clear misunderstanding. Actually I am logged in as a user. No problem with that part. But it looks like auth:: doesn't understand that and when I try to retrieve users. it's redirecting me to login's endpoint...
use Illuminate\Http\Request;
use App\Http\Controllers\Controller;
use Auth;
class UsersController extends Controller
{
public function getUser(){
$users = Auth::user();
dd($users);
}
}
And about the api route:
Route::group(['middleware' => 'auth:api'], function() {
Route::post("logout", "Api\AuthController#logout");
/* User */
Route::get('/user', 'Api\UsersController#getUser');
});
Route::group(["prefix" => "v1"], function(){
/* Auth */
Route::post("login", "Api\AuthController#login")->name("login");
Route::post("register", "Api\AuthController#register");
});
Here is the thing. If I use my UserController route outside the middleware:api then endpoint is returns null. And if use it inside the middleware it redirects me to my login's endpoint. Because of the "->name('login')"
In the end I can't return the users. Additionally this is what config/auth looks like.
'defaults' => [
'guard' => 'web',
'passwords' => 'users',
],
By the way before asked. I tried to change guard's web to api but nothing is changed.
'guards' => [
'web' => [
'driver' => 'session',
'provider' => 'users',
],
'api' => [
'driver' => 'passport',
'provider' => 'users',
],
],
Is there anyone have better understanding on this situation. How can I return users with using passport? Do I missing something here?
Apparently, the problem is with the request header. Only a logged in user can call /api/user endpoint with an access_token in the request header.
Request header will have this pair
Authorization: Bearer eyJ0eXAiOiJKV1..........
Nothing to do in laravel part, as it's working as expected.
If you are using Laravel Passport. Let's read and make your step same in document: https://laravel.com/docs/5.8/passport
From your API request, need to pass the access_token to backend.
Hoping you can resolve that issue!
I try laravel passport.But i can't understand anything.
How check the user is valid or not in Laravel Passport
You can check this.
https://laravel.com/docs/5.5/passport
I will briefly explain.
After you setup Laravel-Passport to your project you should edit driver key in config/auth.php file.
'api' => [
'driver' => 'passport',
'provider' => 'users',
],
And then make migration. Check your database. There must be tables about laravel passport.
You should post the datas below to '/user' url.
'grant_type' => 'authorization_code',
'client_id' => 'client-id',
'client_secret' => 'client-secret',
'username'=>'username',
'password'=>'password',
'scope'=>''
You must edit grant_type, client_id and client_secret keys according to values in the oauth_clients table in your database.
If you get Access-Control-Allow-Origin error you must create a middleware to allow all requests.
if (isset($request->server()['HTTP_ORIGIN'])) {
$origin = $request->server()['HTTP_ORIGIN'];
header('Access-Control-Allow-Origin: ' . $origin);
header('Access-Control-Allow-Headers: Origin, Content-Type, Authorization');
}
return $next($request);