Cakephp 3.7.x How to retrieve user data? using Authentication component - authentication

I am using cakephp 3.7.2 with Authentication component
$user = $this->Authentication->getIdentity();
prints:
object(Authentication\Identity) {
'config' => [
'fieldMap' => [
'id' => 'id'
]
],
'data' => object(App\Model\Entity\User) {
'id' => (int) 1,
'email' => 'aa.aaa#gmail.com',
...
}
}
I have tried $user->data but it doesn't work.
How to print user data?
Authentication Component

So I have figured it out.
In User Entity class
Add use Authentication\IdentityInterface;
and then implement the IdentityInterface.
class User extends Entity implements IdentityInterface
{
blablabla...
yale yale yale ...
Now you can print:
$user = $this->Authentication->getIdentity();
debug($user->id);

As per Authentication component documentation
The identity object is returned by the service and made available in
the request. The object provides a method getIdentifier() that can be
called to get the id of the current log in identity.
You can use this accordingly as below to get the user data:
// Service
$identity = $authenticationService
->getIdentity()
->getIdentifier()
// Component
$identity = $this->Authentication
->getIdentity()
->getIdentifier();
// Request
$identity = $this->request
->getAttribute('identity')
->getIdentifier();
The identity object provides ArrayAccess but as well a get() method to
access data. It is strongly recommended to use the get() method over
array access because the get method is aware of the field mapping.
For eg. to access email and username from the identity you can use the below code.
$identity->get('email'); // to access email
$identity->get('username'); // to access username
Reference link: Authentication -> Docs -> Identity Object
Hope this will help.

I´m using AuthComponent in CakePHP 4.xxx.
I can get User data i.e. in a view with
$user = $this->getRequest()->getAttribute('identity');
I found the Information on: http://gotchahosting.com/blog/category/cakephp/4002624
Maybe it helps someone who is looking for information about this in CakePHP4

Related

How to check if user is logged in, in Shopware 6 Storefront Controller or Subscriber?

I am looking for the right way on how to check, if a user is logged in, in the Shopware 6 storefront. I am writing a plugin (not an app), and want to use this in Controllers and/or Subscribers.
Should I:
Use the Storefront API? (but how? which path?)
Use the default symfony way? (isGranted) - but with which Roles? Isn't the role handling different?
Use some built-in functionality like a special service that I can fetch by Dependeny Injection (but which one?)?
Solution:
Thanks to #Uwe Kleinmann, I found a solution, that works in a subscriber like this:
public static function getSubscribedEvents()
{
return [
ProductPageLoadedEvent::class => 'onProductPageLoaded'
];
}
public function onProductPageLoaded(ProductPageLoadedEvent $event): void
{
$saleschannelContext = $event->getSaleschannelContext();
$customer = $saleschannelContext->getCustomer();
if(NULL === $customer) {
$customer = 'not-logged-in';
}
$event->getPage()->addExtension(
'myextension', new ArrayStruct([
'test' => $customer
])
);
}
The SalesChannelContext has a $customer (accessible with getCustomer()) attribute. This context is usually injected into both Storefront controllers and subscribers for any Storefront events.
It is only set, if the current user is logged-in.
You may also use the _loginRequired and _loginRequiredAllowGuest flags in the #Route annotation of a storefront controller's method. This is handy if you only want to allow access for logged in customers as this will automatically redirect logged out users to the login page and back to the origin after they logged in.
/**
* #Route("/my/custom/page", name="frontend.custom.page", methods={"GET"}, defaults={"_loginRequired"=true, "_loginRequiredAllowGuest"=true})
*/

CakePHP 3.x - Modify user data in Auth component before session creation

When using the Auth component in CakePHP 3 you can define the findAuth() finder (or configure a different finder) to have control over what data is loaded:
// AppController
$this->loadComponent('Auth', [
//...
'authenticate' => [
'Form' => [
'finder' => 'auth'
]
],
//...
]);
// UsersTable
public function findAuth($query, array $options)
{
return $query
->...;
}
I need some functionality that cannot be done with the query builder. How can I post-process the loaded auth data before session creation?
Note that I have different ways of logging in my users, so I would prefer this be kept inside the AuthComponent logic.
(This is still for CakePHP 3, but a brief comment on how this could be done in the new CakePHP 4 Authentication plugion would also be appriciated.)
EDIT: Rough outline of what I need: data needs to re-organised in the users array based on current context, i.e. users can have an active project selected.
I'm still not really sure what exactly you need to re-organize in what way exactly, but generally you can modify the queried data using mappers/reducers and result formatters, the latter usually being the easier way.
Here's a quick example that would add an additional field named additional_data to the result in case a field named active_project_id is set:
$query->formatResults(function (\Cake\Collection\CollectionInterface $results) {
return $results->map(function ($row) {
if (isset($row['active_project_id'])) {
$row['additional_data'] = 'lorem ipsum';
}
return $row;
});
});
Such a finder query would work with the new authentication plugin too.
See also
Cookbook > Database Access & ORM > Query Builder > Adding Calculated Fields

Yii2 Authentication not working as expected

I am working on a micro service. It has basically login and registration. I followed the Yii2 official guide. But now i am facing an issue. When i try to send request to the endpoints which are protected ( Only users with access_token can make request ) It works but very strange it checks all the rows in the database and if access_token is matches any rows in the database then it allows the request. But what i want - I am trying to get users information, if i pass the token i want only the information which belongs to current user ( Whose token is in request ) .
I am doing this in my UserController -
public function behaviors() {
$behaviors = parent::behaviors();
$behaviors['authenticator'] = [
'class' => HttpBearerAuth::className(),
];
$behaviors['authenticator']['only'] = ['view'];
return $behaviors;
}
And in User model have implemented this method -
public static function findIdentityByAccessToken($token, $type = null) {
return static::findOne(['access_token' => $token]);
}
Where i am doing wrong?
If the access_token in the request matches the access_token value for any of the users in the database, then, like you say, the authentication filter will forward the request to the corresponding action on your controller.
At this point the application user component points to the user that was found, you can use the user's component id to recover the record matching the request's user from the database.
// Get the user record
$current_user = Yii::$app->user->identity;
// Do something with the user record
return [
'username' => $current_user->username,
'last_update' => $current_user->updated_at
...
];

Laravel 5 - creating two tables during registration

In my database design, I have two tables, People & Auth. The Auth table holds authentication information and the person_id while the People table holds all other information (name, address, etc). There is a one-to-one relationship between the tables as seen in the models below.
The reason I have separated the data into two tables is because in my
application, I will have many people who do not have authentication
capabilities (customers to the user).
App/Auth.php
class Auth extends Model implements AuthenticatableContract, AuthorizableContract, CanResetPasswordContract
{
use Authenticatable, Authorizable, CanResetPassword;
public function person() {
$this->belongsTo('Person');
}
}
App/Person.php
class Person extends Model
{
public function auth() {
$this->hasOne('Auth');
}
}
In my AuthController::create() method, I am attempting to populate both models with the user supplied information like this:
protected function create(Request $request)
{
$person = \App\Person::create($request->all());
$auth = new \App\Auth;
$auth->fill($request->all());
$auth->person_id = $person->id;
$auth->save();
return $person;
}
In my application, I would like to authorize a user and pass a $user object as the authenticated person to subsequent routes. Am I doing this correctly? Is this the best way? There's cookies and bonus points if you can also explain how to retrieve the $user object after authentication...Auth table data is not needed in the $user object.
EDIT
I have changed my config/Auth.php file to reflect the changes as noted in the answers below (thx #user3702268). However, I have now found an error with my controller. In the AuthController::create() method, I am returning my App/Person object and this throws an ErrorException seeing as how App/Person does not implement the Authorizable trait. I do not want my App/Person object to be authorizable, but it is the object that I want returned as the authenticated $user in my views. How? Shall I simply override the postRegister method or is there a more Laravel way?
EDIT 2
I'm now returning the $auth object which uses the authorizable trait. In my views/controllers I'm trying to access the Person using Auth::user()->person but getting Class 'Person' not found errors
You should replace the App\User Class in config/auth.php line 31 the class that contains the username and password:
'model' => App\User::class,
to
'model' => App\Auth::class,
Be sure to encrypt the password before saving by using the bcrypt($request->get('password')) helper or Hash::make($request->get('password')). Then you can authenticate by calling:
Auth::attempt([$request->get('username'), $request->get('password')]);
You can retrieve the authenticated user using this:
Auth::user()

ZF2 Authentication

i am developing an application using ZF2. I have done the user authentication with username & password. But, i would like to check an additional column(example: status) in authentication.
I have done the following codes.
public function authenticate()
{
$this->authAdapter = new AuthAdapter($this->dbAdapter,
'usertable',
'username',
'password'
);
$this->authAdapter->setIdentity($this->username)
->setCredential($this->password)
->setCredentialTreatment('MD5(?)');
$result = $this->authAdapter->authenticate();
return $result;
}
How can i check the column 'status' in authentication?
Note: status value should be 1.
Thanks.
When I was building my authentication using zf2 and doctrine, I have created authorization plugin and customized this adapter for passing extra column for authentication.
You probably need to go on similar directions.
$adapter = new AuthAdapter($db,
'users',
'username',
'password',
'MD5(?)'
);
// get select object (by reference)
$select = $adapter->getDbSelect();
$select->where('active = "TRUE"');
// authenticate, this ensures that users.active = TRUE
$adapter->authenticate();
Reference
After changes your code should look something like this.
public function authenticate()
{
$this->authAdapter = new AuthAdapter($this->dbAdapter,
'usertable',
'username',
'password'
);
$select = $this->authAdapter->getDbSelect();
$select->where('status= "1"');
$this->authAdapter->setIdentity($this->username)
->setCredential($this->password)
->setCredentialTreatment('MD5(?)');
$result = $this->authAdapter->authenticate();
return $result;
}
ZF2 provides a another way to handle additional checks using other columns than the ones foreseen for identity and credential thanks to the method getResultRowObject. All columns of usertable in your example are available as properties of the object returned by getResultRowObject(). So you could expand your code with this :
if ($result->isValid()) {
$identityRowObject = $this->authAdapter->getResultRowObject();
$status = $identityRowObject->status;
// do whatever complex checking you need with $status...
}
Regards,
Marc