I am working on project which has separate model for users — App\Models\Customer. And also it has own authorisation fields — Email and cust_password. And also password is hashed by password_hash function.
In my config/auth.php in providers section I set up my custom model:
'providers' => [
'customers' => [
'driver' => 'eloquent',
'model' => App\Models\Customer::class,
],
],
So I am trying to implement Laravel Grand Tokens. I need to make request to /oauth/token/ with client (which was previously created with custom provider field) and customer credentials as like this:
/** #var \Laravel\Passport\Client $client */
$response = Http::asForm
->post('https://localhost/oauth/token/', [
'grant_type' => 'password',
'client_id' => $client->id,
'client_secret' => $client->secret,
'username' => 'example#example.com',
'password' => password_hash('my-password'),
]);
But I am receiving error: invalid_grant — The user credentials were incorrect.
I assume that Passport doesn't know where to find my Email and cust_password fields. Is there any way to set custom login and password fiends?
Thanks you any advice!
Well, I wasn't attentive enough, there is special topics for this situations:
Customizing The Username Field https://laravel.com/docs/9.x/passport#customizing-the-username-field
Customizing The Password Validation https://laravel.com/docs/9.x/passport#customizing-the-password-validation
Related
i created laravel cms using vue and axios.
i want get current user that sending post requests
so i followed laravel api documentation and take this structure
// bootstrap.js
window.axios = require('axios');
window.axios.defaults.headers.common['X-Requested-With'] = 'XMLHttpRequest';
window.axios.defaults.headers.common['Authorization'] = `Bearer ${window.api_token}`;
// vue component file
axios.post('/api/v1/person', this.person)
.then(data => {
this.$emit('added', data.data);
this.person.id = data.data.data.id
});
// Route in api.php
Route::prefix('v1')->name('api.')->group(function () {
/** Person Routes */
Route::prefix('person')->namespace('Person')->name('person.')->group(function(){
Route::post('/', 'PersonController#index');
});
});
//in laravel controller i retrun
return response()->json(auth('api')->user());
but i get this result
even i checked console headers and Authorization header set properly
i can get all post data but laravel don`t pass me the user
also i made a repository of this project in github
if you want can follow this link
https://github.com/mohammadZx/crm
In the documentation it states that you have to set the correct guard for Passport to work. Update auth.php config.
'guards' => [
'api' => [
'driver' => 'passport',
'provider' => 'users',
],
],
by default, laravel trying to find user by hashing token and for this reason laravel return null because your user api tokens not hashed. so if you change auth.php setting to don't searching hashes api_tokens, this problem will be fixed
'guards' => [
'api' => [
'driver' => 'token',
'provider' => 'users',
'hash' => false
],
],
I'm developing an API for an application that I'm creating. This application will get all the information from this API (first will auth the user, then get information)
Right now, I'm trying to make the user send a username and password to the API, it validates the information and returns if it's "ok" or "not", very simple to start only. I know all the security involved in this, just need to get this working.
Already managed to send the username and passsword on the API Side (and i'm 100% sure that the data is correctly saved). Though, when I call
$this->Auth->identify($this->request->data);
It always returns false to me (already tried with parameters and without, result is the same).
I'm using the HttpRequester, firefox plugin, to send information.
I've did a debug of $this->request->data to see if the information is correct, and it is. Can't do a find on database since the password is being hashed.
The database password field is a varchar with 300 length (already tried with 255, also no work)
Thanks for the help
EDIT:
$this->loadComponent('Auth', [
'authenticate' => [
'Form' => [
'fields' => [
'username' => 'email',
'password' => 'password'
]
],
]
]);
if($this->request->is('POST')){
//debug($this->request->data);
$user = $this->Auth->identify($this->request->data);
}
Users Table:
protected $_accessible = [
'*' => true,
];
/**
* Hash password
*
*/
protected function _setPassword($password)
{
return (new DefaultPasswordHasher)->hash($password);
}
protected function _getFullName()
{
if(isset($this->_properties['full_name'])){
return ucwords(mb_strtolower($this->_properties['full_name']));
}
}
ps: Also tried doing the following (replacing the variables form post, but also no luck)
$this->request->data['username'] = "xxxx";
$this->request->data['password'] = "zzzz";
Problem is here
'Form' => [
'fields' => [
'username' => 'email', //email is your database field
'password' => 'password' // password is your database field name
]
],
Your code should be
'Form' => [
'fields' => [
'username' => 'username',
'password' => 'password'
]
],
Details check Configuring Authentication Handlers
I have two tables for admin and client with two different login method for each type of user.
I use attempt() method for admin already. I am trying to create JWTAuthentication for clients. At this moment when i am trying to authenticate client login , laravel queries inside admin table while I want it to query inside client table. I tried to set config to specifically look into client model. But it is still looking into Admin.
How do i tell laravel to avoid looking into admin table when client is trying to login?
if($dbPass==$password)
{
//find secret api key and send it to curl
//$this->callTeamworkApi($query->secretApiKey);
//set session
//JWT authenticate
//$credentials = ["email"=>$email,"password"=>$password];
//$credentials = $request->all('email','password');
$credentials =[];
$credentials['email'] = $email;
$credentials['password'] = $request->password;
try{
\Config::set('auth.model', 'Client');
\Config::set( 'auth.table' , 'clients' );
if( ! $token = JWTAuth::attempt($credentials))
{
return response()->json([
'response' => 'Some error with user credentials'
]);
}else{
// $request->session()->put('secretApiKey', $query->secretApiKey);
// $request->session()->put('userEmail', $sessionEmail);
// $request->session()->put('userId', $sessionId);
// $request->session()->put('userName', $sessionName);
// $request->session()->put('timeCreated', $timeCreated);
//find user details and put them inside session array
$msg = "Login_checked";
return response()->json(["token"=>compact('token'), "msg"=> $msg]);
}
}catch(JWTExceptions $err){
return response()->json(['response'=>$err]);
}
}else{
$msg = "Password_wrong";
}
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 should configure multiple
sources which represent each model / table.
this should be done in config/auth.php file.
'providers' => [
'admins' => [
'driver' => 'eloquent',
'model' => App\Admin::class,
],
'clients' => [
'driver' => 'eloquent',
'model' => App\Client::class,
],
],
This works in Laravel 5, I'm not sure about version 4 and below.
I have 2 different tables user and organiser and i am trying to create 2 different login for both users.
I am able to sign them up easily and get the record in database but after saving the record i get the error on following code line
if ($user = $model->signup()) {
if (Yii::$app->getUser()->login($user)) { //yii\web\IdentityInterface error
return $this->goHome();
}
}
Following is my configuration module
'components' => [
'user' => [
'identityClass' => 'common\models\User',
'enableAutoLogin' => true,
'identityCookie' => [
'name' => '_frontendOrganiser', // unique for frontend
],
],
'users' => [
'class' => 'yii\web\User',
'identityClass' => 'common\models\Users',
'enableAutoLogin' => false,
'enableSession' => true,
'identityCookie' => [
'name' => '_frontendUser', // unique for frontend
],
],
'session' => [
'name' => 'PHPFRONTSESSID',
'savePath' => sys_get_temp_dir(),
],
]
So what is wrong am i doing here? Do i need to create any other Interface or something or provide different interface for different module?
And i had to do this because organiser table uses password_hash technique to log in the users where my user table is from another project and they uses md5 technique, so i had to create separate module for both users.
Argument 1 passed to yii\web\User::login() must be an instance of yii\web\IdentityInterface, instance of common\models\Users given, called in C:\xampp\htdocs\project\frontend\controllers\SiteController.php on line 202 and defined
The exact error statement is as above.
I think your user model don't implement the Identity interface correctly.
Try check you data model also (in your DB) this must contain all the field managed bay the interface.
And be sure you User implement the Identity Interface correctly.
and mapping the interface method with your model correctly..
See the interface doc for this http://www.yiiframework.com/doc-2.0/yii-web-identityinterface.html
Sometimes, we'd like to separate users and admins in different 2 tables.
I think it is a good practice.
I am looking if that is possible in Laravel 5.
Before reading the following, you are supposed to have basic knowledge on ServiceProvider, Facade and IoC in Laravel 5. Here we go.
According to the doc of Laravel, you could find the Facade 'Auth' is refering to the Illuminate\Auth\AuthManager, which has a magic __call(). You could see the major function is not in AuthManager, but in Illuminate\Auth\Guard
Guard has a Provider. This provider has a $model property, according to which the EloquentUserProvider would create this model by "new $model". These are all we need to know. Here goes the code.
1.We need to create a AdminAuthServiceProvider.
public function register(){
Auth::extend('adminEloquent', function($app){
// you can use Config::get() to retrieve the model class name from config file
$myProvider = new EloquentUserProvider($app['hash'], '\App\AdminModel')
return new Guard($myProvider, $app['session.store']);
})
$app->singleton('auth.driver_admin', function($app){
return Auth::driver('adminEloquent');
});
}
2.Facade:
class AdminAuth extends Facade {
protected static function getFacadeAccessor() { return 'auth.driver_admin'; }
}
3. add the alias to Kernel:
'aliases' => [
//has to be beneath the 'Auth' alias
'AdminAuth' => '\App\Facades\AdminAuth'
]
Hope this could be helpful.
I have created a laravel package where you can handle multiple authentication.
Step 1 : Composer require
Firstly, composer require the multiauth package
composer require sarav/laravel-multiauth dev-master
Step 2 : Replacing default auth service provider
Replace
Illuminate\Auth\AuthServiceProvider::class
with
Sarav\Multiauth\MultiauthServiceProvider
in your config/app.php file
Step 3 : Modify auth.php
Modify your config/auth.php file to something like this
'multi' => [
'user' => [
'driver' => 'eloquent',
'model' => App\User::class,
'table' => 'users'
],
'admin' => [
'driver' => 'eloquent',
'model' => App\Admin::class,
'table' => 'admins'
]
],
Thats it! Now you can try multiple authentication by passing the user as first parameter. For example
\Auth::loginUsingId("user", 1); // Login user with id 1
\Auth::loginUsingId("admin", 1); // Login admin with id 1
// Attempts to login user with email id johndoe#gmail.com
\Auth::attempt("user", ['email' => 'johndoe#gmail.com', 'password' => 'password']);
// Attempts to login admin with email id johndoe#gmail.com
\Auth::attempt("admin", ['email' => 'johndoe#gmail.com', 'password' => 'password']);
For more detailed documentation
http://sarav.co/blog/multiple-authentication-in-laravel/
http://sarav.co/blog/multiple-authentication-in-laravel-continued/