I am using fresh install of Laravel 8 and passport to create oauth2 server. To test with the client I use Postman. Following this guide https://laravel.com/docs/8.x/passport#introduction here are all the changes I've made:
AuthServiceProvider.php:
<?php
namespace App\Providers;
use Illuminate\Foundation\Support\Providers\AuthServiceProvider as ServiceProvider;
use Illuminate\Support\Facades\Gate;
use Laravel\Passport\Passport;
class AuthServiceProvider extends ServiceProvider
{
/**
* The policy mappings for the application.
*
* @var array
*/
protected $policies = [
'App\Models\Model' => 'App\Policies\ModelPolicy',
];
/**
* Register any authentication / authorization services.
*
* @return void
*/
public function boot()
{
$this->registerPolicies();
//
if (! $this->app->routesAreCached()) {
Passport::routes();
}
Passport::loadKeysFrom(__DIR__.'/../secrets/oauth');
Passport::tokensExpireIn(now()->addDays(15));
Passport::refreshTokensExpireIn(now()->addDays(30));
Passport::personalAccessTokensExpireIn(now()->addMonths(6));
}
}
Here is the function responsible for the login:
public function store(LoginRequest $request)
{
$validator = Validator::make($request->all(), [
'email' => 'required|email',
'password' => 'required',
]);
if ($validator->passes()) {
$credentials = array(
'email' => $request->email,
'password' => hash('sha512', $request->password)
);
if (User::where($credentials)->exists()) {
$user = User::where($credentials)->first();
Auth::login($user, isset($request->remember));
if (isset($request->query()['return_to'])) {
return redirect($request->query()['return_to']);
} else {
return redirect()->intended(RouteServiceProvider::HOME);
}
} else {
return redirect()->route('login');
}
} else {
return redirect()->route('login', ['error' => $validator->errors()->first()]);
}
/*
$request->authenticate();
$request->session()->regenerate();
return redirect()->intended(RouteServiceProvider::HOME);*/
}
My config/auth.php:
<?php
return [
/*
|--------------------------------------------------------------------------
| Authentication Defaults
|--------------------------------------------------------------------------
|
| This option controls the default authentication "guard" and password
| reset options for your application. You may change these defaults
| as required, but they're a perfect start for most applications.
|
*/
'defaults' => [
'guard' => 'web',
'passwords' => 'users',
],
/*
|--------------------------------------------------------------------------
| Authentication Guards
|--------------------------------------------------------------------------
|
| Next, you may define every authentication guard for your application.
| Of course, a great default configuration has been defined for you
| here which uses session storage and the Eloquent user provider.
|
| All authentication drivers have a user provider. This defines how the
| users are actually retrieved out of your database or other storage
| mechanisms used by this application to persist your user's data.
|
| Supported: "session"
|
*/
'guards' => [
'web' => [
'driver' => 'session',
'provider' => 'users',
],
'api' => [
'driver' => 'passport',
'provider' => 'users',
],
],
/*
|--------------------------------------------------------------------------
| User Providers
|--------------------------------------------------------------------------
|
| All authentication drivers have a user provider. This defines how the
| users are actually retrieved out of your database or other storage
| mechanisms used by this application to persist your user's data.
|
| If you have multiple user tables or models you may configure multiple
| sources which represent each model / table. These sources may then
| be assigned to any extra authentication guards you have defined.
|
| Supported: "database", "eloquent"
|
*/
'providers' => [
'users' => [
'driver' => 'eloquent',
'model' => App\Models\User::class,
],
// 'users' => [
// 'driver' => 'database',
// 'table' => 'users',
// ],
],
/*
|--------------------------------------------------------------------------
| Resetting Passwords
|--------------------------------------------------------------------------
|
| You may specify multiple password reset configurations if you have more
| than one user table or model in the application and you want to have
| separate password reset settings based on the specific user types.
|
| The expire time is the number of minutes that the reset token should be
| considered valid. This security feature keeps tokens short-lived so
| they have less time to be guessed. You may change this as needed.
|
*/
'passwords' => [
'users' => [
'provider' => 'users',
'table' => 'password_resets',
'expire' => 60,
'throttle' => 60,
],
],
/*
|--------------------------------------------------------------------------
| Password Confirmation Timeout
|--------------------------------------------------------------------------
|
| Here you may define the amount of seconds before a password confirmation
| times out and the user is prompted to re-enter their password via the
| confirmation screen. By default, the timeout lasts for three hours.
|
*/
'password_timeout' => 10800,
];
This is my User.php model:
<?php
namespace App\Models;
use Illuminate\Contracts\Auth\MustVerifyEmail;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Foundation\Auth\User as Authenticatable;
use Illuminate\Notifications\Notifiable;
use Laravel\Sanctum\HasApiTokens;
class User extends Authenticatable
{
use HasApiTokens, HasFactory, Notifiable;
/**
* The attributes that are mass assignable.
*
* @var string[]
*/
protected $fillable = [
'name',
'email',
'password',
];
/**
* The attributes that should be hidden for serialization.
*
* @var array
*/
protected $hidden = [
'password',
'remember_token',
];
/**
* The attributes that should be cast.
*
* @var array
*/
protected $casts = [
'email_verified_at' => 'datetime',
];
}
Because it's all development let me share my secret and client ids:
Than here are my Postman requests:
When I execute the following link:
http://127.0.0.1:10000/oauth/authorize?client_id=2&redirect_uri=http://127.0.0.1:8000/authorize/response&response_type=code&scope&state=asdadasdasasfafasadas
This sends me to a login page where I do successful login and I get redirected to:
http://127.0.0.1:8000/authorize/response?code=def502004c696cf8720f807b6dd488df865f6a76ace0a7793f09ad6cbc6799f3e7028863bf59d8e681263c99663b5222ad71dd4ed7e8ec7e0111281409ba46d5a885ab849dd578a76ea49c755ad403b9072eb75e3d341d9d1a0b017afa1d446f92fa05e593698df39230fee2eafc1e6ff9461216c56c7e2d516748c370cd619e70f7eb426a13b03609b79fa7f7f40c7581057ec8373700a54049696fea00a3f51fcef2583ea0b6f07c873a962f19e1c50367caea0922ba5f919f7853e2bb114ba8ca6192d009fcde38ff620e0d769dda66ff1bdd8f7b5180e6d9205401f8154c99bb777a41d07f27d150390084e5ced4d4ebb57a64950d09a9a4c7bc3fff1c49d8adcf628b506d08ceae122ff32eacfb540b310483d507db9af3f448e7f93b60b35238c34093adcb9807712ccd0a65f2b1dc38621e372df33182b87655f6f78339d8d3a6cc8c63f31bf6f6888c4c98a76efb6f9ce09803b292e95b7bf71ac8f931a9f1615fdba8fa4374&state=asdadasdasasfafasadas
Than I do this request in Postman:
As you can see I am using the code given from the above last link. Here it is in whole:
def502004c696cf8720f807b6dd488df865f6a76ace0a7793f09ad6cbc6799f3e7028863bf59d8e681263c99663b5222ad71dd4ed7e8ec7e0111281409ba46d5a885ab849dd578a76ea49c755ad403b9072eb75e3d341d9d1a0b017afa1d446f92fa05e593698df39230fee2eafc1e6ff9461216c56c7e2d516748c370cd619e70f7eb426a13b03609b79fa7f7f40c7581057ec8373700a54049696fea00a3f51fcef2583ea0b6f07c873a962f19e1c50367caea0922ba5f919f7853e2bb114ba8ca6192d009fcde38ff620e0d769dda66ff1bdd8f7b5180e6d9205401f8154c99bb777a41d07f27d150390084e5ced4d4ebb57a64950d09a9a4c7bc3fff1c49d8adcf628b506d08ceae122ff32eacfb540b310483d507db9af3f448e7f93b60b35238c34093adcb9807712ccd0a65f2b1dc38621e372df33182b87655f6f78339d8d3a6cc8c63f31bf6f6888c4c98a76efb6f9ce09803b292e95b7bf71ac8f931a9f1615fdba8fa4374
However I receive the following error as you can see in the above screenshot:
{
"error": "invalid_client",
"error_description": "Client authentication failed",
"message": "Client authentication failed"
}
Why do I receive this error? How can I fix it. As you can see I am sending correct information but nonetheless I get and error, why ?

