How can I use another table for authentication in Laravel 7 - authentication

Im very new with Laravel and had already seen many tutorials, so now I know little more. But I am struggling with a problem that I can't solve. I want to use another table(t_clients) that already exists in my DB instead of users table made by migration for authentication. I already read the documentation on website , so I changed in auth.php this:
'providers' => [
// 'users' => [
// 'driver' => 'eloquent',
// 'model' => App\User::class,
// ],
'users' => [
'driver' => 'database',
'table' => 't_clients',
],
],
Now when I try to login I get the next error : ErrorException Undefined index: id. So I tried the next one and this problem is temporary fixed, I changed the primary_key name in the table "t_clients" to "id" and login works. The original column name is "pk_client". But I want actually that the primary_key remains unchanged. I want actually that by authentication, Laravel search for "pk_client" and not "id". Does anyone know how I can fix this? I appreciate your help.
Spec project:
Laravel Framework 7.1.0
mysql Ver 8.0.18

This problem was fixed by making a Client EloquentModel and add de next lines:
protected $table = 't_clients';
protected $primaryKey = 'pk_client';
So the result should be:
class Client extends Authenticatable implements CanResetPassword
{
protected $table = 't_clients';
protected $primaryKey = 'pk_client';
use Notifiable;
}

Related

"Attempt to read property \"id\" on null", Create access token error with laravel passport, laravel 9, php 8.2.2

devs,
so I have been struggling with this problem for about 10 hours now, and I can't seem to find a solution online, worst is that I don't even know why it happens.
I am working on a project which uses PHP LARAVEL as the backend and I started writing the API for the flutter frontend to consume then I ran into this error while trying to test the API endpoint for registering and logging in.
The problem is the process fails with this error when I try to generate or create a token for the registered user or logged-in user.
Here a snapshot of my register function
public function store(Request $request)
{
$validated = Validator::make($request->all(),[
"email" => "required|email",
"password" => 'required',
"first_name"=> "required",
"last_name" => "required",
"phone_number" => 'required',
]);
if ($validated->fails()) {
return response()->json(['errors' => "Invalide credentials"], 403);
}
$user = User::create(
// [
// 'first_name' => $request->first_name,
// 'last_name'=> $request->last_name,
// 'email' => $request->email,
// 'password' => bcrypt($request->password),
// 'phone_number' => $request->phone_number,
// ]
$request->toArray()
);
Auth::guard('api')->check($user);
// $newUser = User::find($user->id);
$token = $user->createToken('authToken')->accessToken;
// return $token;
return response(['token' => $token, 'first_name'=>$user->first_name, 'email'=>$user->email ], 200);
}
The login and register functions all look the same at this point.
Error-causing code is :
$token = $user->createToken('authToken')->accessToken;
Please I am open to your suggestions, thanks.
I finally found a solution for this error and I believe it will help anyone out there with a similar problem.
The problem originates from the fact that your application is unable to asign a unique id to your client, remember your website or mobile app is a client to the backend with also(your mobile app or website) might have other users, so laravel passport will need to identify it with a unique id, below are some of the steps i used to fix this error.
First it originates because during the passport installation, i forgot to install
Blockquote
--uuids
If you have a similar error, follow the steps below to fix:
NOTE: You must have laravel passport installed already, if not, them follow the complete installtion guide Here
Step 1:
Install passport uuids
php artisan passport:install --uuids
Your result will look something like
After creating, the uuid for your application, you will have to include it in your .env file as such:
PASSPORT_PERSONAL_ACCESS_CLIENT_ID=986eb40c-0458-4b6e-bead-ea2fc4987033
PASSPORT_PERSONAL_ACCESS_CLIENT_SECRET=VXLdTpqWK9i3CBqFwZgje5fuerQ5Uf2lvwXJqBoP
And there you go, you can now try to do what you couldn't do before.

Creating auth tokens for a custom model that is not the default User model

How do I create access/api/auth tokens for a different model? From most questions, docs, or tutorials, most are using the default User model.
I read the default doc but it doesn't really say where to substitute the default Model class or how to verify against non-Model classes.
Any suggestions?
To use a different model than User for Laravel Sanctum API authentication.
This is for Laravel 8.
Create new model, php artisan make:model ModelName -m
the flag m is used to instantiate a migration file for this model.
Go to the Model class file and extend it with Illuminate\Foundation\Auth\User, ensure it uses HasApiTokens, and list out your fillable fields for record creation.
...
use Illuminate\Foundation\Auth\User as Authenticatable;
class ModelName extends Authenticatable{
use ..., HasApiTokens;
protected $fillable = [...]
}
Go to config/auth.php and add new provider and new guard.
'guards' => [
...
,
'api' => [
'driver' => 'sanctum',
'provider' => 'model-name',
'hash' => false,
]
],
'providers' => [
...
,
'model-name' => [
'driver' => 'eloquent',
'model' => App\Models\ModelName::class,
]
]
Go to your api routes and wrap your routes as below.
Route::middleware(['auth:sanctum'])->group(function(){
Route::get('/whatever-route-name',function(){
return 'Authenticated';
});
});
Download Postman or your favored API testing tool, send a GET request to [http://localhost:8000/api/whatever-route-name](http://localhost:8000/api/whatever-route-name) , in Headers, ensure Accept has a value of applcation/json, send the request, and it should return an {”message”: “Unauthenticated.”}
Go to your public routes, create a dummy route to create a record for ModelName
After creation ensure that you call $model_name→createToken($model_name→whatever_field)→plaintTextToken; to get the plain text api key.
Go to back to your API test tool, under Authorization, choose Bearer Token and supply the api key returned from above.
The route wrapped in auth:sanctum is now accessible.

How to assign an Owner using the Hubspot API?

I'm using the Hubspot API to create new contacts and would like to automatically set the owner when the contact is created. I know this is possible without using the API via Workflows, however I'd like to use the API for that.
Here's my code right now (which works, just missing the contact owner):
$data = [
'properties' => [
['property' => 'firstname', 'value' => $contact->first_name],
['property' => 'lastname', 'value' => $contact->last_name],
]
];
$body = json_encode($data);
$response = $client->request('POST', '/contacts/v1/contact/email/'.$user->email.'/profile',
['query' => ['hapikey' => $hubspot_key, 'body' => $body]);
I eventually found a way to achieve this:
Go to your Hubspot instance, then Settings and Properties
Search for "Contact Owner" and click on Edit
In "Field type", identify the Owner's ID value
Then in your API call, simply pass this property:
$data['properties'][] = ['property' => 'hubspot_owner_id', 'value' => 123456];
You can find out more about the hubspot_owner_id property (which is internal to Hubspot, this is not a custom property) in Hubspot's documentation.
It will automatically assign the newly created (or updated) Hubspot contact to the related Owner (Hubspot User).

Passport - "Unauthenticated." - Laravel 5.3

I hope someone could explain why I'm unauthenticated when already has performed a successfull Oauth 2 authentication process.
I've set up the Passport package like in Laravel's documentation and I successfully get authenticated, receives a token value and so on. But, when I try to do a get request on, let say, /api/user, I get a Unauthenticated error as a response. I use the token value as a header with key name Authorization, just as described in the docs.
Route::get('/user', function (Request $request) {
return $request->user();
})->middleware("auth:api");
This function is suppose to give back my self as the authenticated user, but I'm only getting Unauthenticated. Likewise, if I just return the first user, I'm again getting Unauthenticated.
Route::get('/test', function(Request $request) {
return App\User::whereId(1)->first();
})->middleware("auth:api");
In a tutorial from Laracast, guiding through the setup of Passport, the guider doesn't have the ->middleware("auth:api") in his routes. But if its not there, well then there's no need for authentication at all!
Please, any suggestions or answers are more then welcome!
You have to set an expiration date for the tokens you are generating,
set the boot method in your AuthServiceProvider to something like the code below and try generating a new token. Passports default expiration returns a negative number
public function boot()
{
$this->registerPolicies();
Passport::routes();
Passport::tokensExpireIn(Carbon::now()->addDays(15));
Passport::refreshTokensExpireIn(Carbon::now()->addDays(30));
}
Check your user model and the database table, if you have modified the primary id field name to say something other than "id" or even "user_id" you MIGHT run into issues. I debugged an issue regarding modifying the primary id field in my user model and database table to say "acct_id" instead of keeping it as just "id" and the result was "Unauthenticated" When I tried to get the user object via GET /user through the auth:api middleware. Keep in mind I had tried every other fix under the sun until I decided to debug it myself.
ALSO Be sure to UPDATE your passport. As it has had some changes made to it in recent weeks.
I'll link my reference below, it's VERY detailed and well defined as to what I did and how I got to the solution.
Enjoy!
https://github.com/laravel/passport/issues/151
I had this error because of that I deleted passport mysql tables(php artisan migrate:fresh), php artisan passport:install helps me. Remember that after removing tables, you need to re-install passport!
I had exactly the same error because I forgot to put http before the project name.
use Illuminate\Http\Request;
Route::get('/', function () {
$query = http_build_query([
'client_id' => 3,
'redirect_uri' => 'http://consumer.dev/callback',
'response_type' => 'code',
'scope' => '',
]);
// The redirect URL should start with http://
return redirect('passport.dev/oauth/authorize?'.$query);
});
Route::get('/callback', function (Request $request) {
$http = new GuzzleHttp\Client;
$response = $http->post('http://passport.dev/oauth/token', [
'form_params' => [
'grant_type' => 'authorization_code',
'client_id' => 3,
'client_secret' => 'M8y4u77AFmHyYp4clJrYTWdkbua1ftPEUbciW8aq',
'redirect_uri' => 'http://consumer.dev/callback',
'code' => $request->code,
],
]);
return json_decode((string) $response->getBody(), true);
});

Get user details in Yii framework

I am new to Yii framework and I want to get the user details of current logged in user like userid, username & his avatar and want to add that data in the head tag. I am using basic version on Yii.
How can I get this details?
Yii handles user data in the session using the IdentityInterface.
Let's go step by step.
You can create a class, call it User, which implements IdentityInterface. If connected with the database you can extend it to ActiveRecord, totally up to your architecture.
class User extends ActiveRecord implements IdentityInterface
{
...
}
Add the configuration details into the config file, main.php. I work on advance template, thus its located into fronted/config. Check it for the basic one.
'components' => [
...
'user' => [
'identityClass' => 'common\models\User',
'enableAutoLogin' => true,
'identityCookie' => ['name' => '_identity-frontend', 'httpOnly' => true],
],
....
];
This tells the app to get the user session details form the common\model\User class. Its in common as I use the same class for backend and the frontend, which is not the case in the basic template.
Make user login into the app
When you get the object of the User class, with valid username and password, use the following code to login the user.
Yii::$app->user->login($user);
To get the value of the user you have following sample
Yii::$app->user->isGuest - This tells you whether the user is logged in or not.
Yii::$app->user->id - Get the id of the user
Yii::$app->user->identity->name - Yii::$app->user->identity will give you access to the entire object of the User class. If you have any other attributes, use the identity and get those. Example, you can have 'avatar', which stores the avatar url, you can get it by Yii::$app->user->identity->avatar.
Finally to logout
Yii::$app->user->logout();
Use the setState method.
In your UserIdentity.php:
public function authenticate()
{
$user=User::model()->find('LOWER(username)=?',array(strtolower($this->username)));
if($user===null)
$this->errorCode=self::ERROR_USERNAME_INVALID;
else if(!$user->validatePassword($this->password))
$this->errorCode=self::ERROR_PASSWORD_INVALID;
else
{
$this->_id=$user->id;
$this->username=$user->username;
$this->setState("userid",$user->user_id);// set States like this
$this->setState("username",$user->username);
$this->setState("avatar",$user->avatar );
$this->errorCode=self::ERROR_NONE;
}
return $this->errorCode;
}
Now anywhere get these like:
$userid = Yii::app()->user->getState('userid');