Multiple users at the same time with cookie storage

jeremy
Member | 46
+
0
-

Hi, I have backend and frontend users and when I am in frontend I need to have both backend and frontend users logged in at the same time.

Both authentications use the cookie storage and as far as I know all you should need to do is simply set different cookie name for each user, which is pretty much obvious.

However the ‘security.user’ can apparently only have 1 identity at the same time which means that the frontend user replaces the backend identity. Do I need to create a new ‘security.user’ service (for example ‘frontend.security.user’) and use that object for the second identity? Or am I missing a way to have multiple identities within the same user object?

Thanks!

Last edited by jeremy (2022-09-03 22:22)

jeremy
Member | 46
+
0
-

Petr Parolek wrote:

Look at https://doc.nette.org/…thentication#…

Yes, I've already seen that. Namespaces are however only possible with session storage.
There isn't really explained how to do that with cookie storage. I simply tried to do the authentication using 2 different cookies, which works only if I am not trying to use both users at the same time.

Pepino
Member | 249
+
0
-
$this->user->getStorage()->setCookieParameters('admin');
jeremy
Member | 46
+
0
-

Pepino wrote:

$this->user->getStorage()->setCookieParameters('admin');

Thanks, I already tried this.

Maybe I am not explaining my issue. I need to be able to work with both users in the same presenter.
For example:

protected function startup(): void {
	parent::startup();

	if ($this->backendUser->isLoggedIn()) {
		...
	}

	if ($this->frontedUser->isLoggedIn()) {
		...
	}
}

The problem is that both backend and frontend users have the exact same values. Which is why I now think I actually need to create a second User service in order to be able to use both.

Last edited by jeremy (2022-09-04 23:32)

Bulldog
Member | 110
+
-1
-

Do not use two user accounts. Instead, distinguish what a user can do using a roles and acl.

Last edited by Bulldog (2022-09-05 14:10)

Marek Bartoš
Nette Blogger | 1164
+
+1
-

You are right, you have to create second Nette\Security\User service. Unless you want to switch storage context before every single call, which I am not sure would work correctly.

Configuration may look like this:

namespace App\Auth\Admin;

class AdminUser extends \Nette\Security\User {}
services:
  securityAdmin.storage:
    create: Nette\Bridges\SecurityHttp\CookieStorage
    setup:
      - setCookieParameters(name: 'adminLogin')

  securityAdmin.user:
    create: App\Auth\Admin\AdminUser
    autowired: 'self' # only autowire by exact type that service returns (same as 'factory', when 'type' is not specified)
    arguments:
      storage: @securityAdmin.storage
      authorizator: @security.authorizator # reuses authorizator from default extension

It's probably minimal configuration that could work.
Extension is not designed to be registered twice, so I wouldn't use it.
Neither is storage, so we have to register own storage for second user.
Tracy panel could be registered manually.
I am reusing authorizer in example, because imho there is no good reason to have different names or privilege checks for the same actions on admin and public part of a website.

In .latte template, $user is instance of the front user. Autowiring by Nette\Security\User also gives you the front user. I would change that and configure front user the same way as admin, to always be sure. You would have to send it to template explicitly and $this->getUser()/$this->user in Presenter would not work, but otherwise it should not affect any internals from Nette. You would use following config:

namespace App\Auth\Front;

class FrontUser extends \Nette\Security\User {}
services:
  security.user:
    create: App\Auth\Front\FrontUser
    autowired: 'self'

Btw, what is your usecase? We needed this for eshop, where B2B and B2C users have different functionalities on public site and admin needed to test them easily both.

Eventually, you could use similar solution (I created) which solves this problem out of the box, but API, even being quite similar with nette/security, is currently incompatible. It's called orisai/auth (with nette-auth as a Nette di+Tracy integration). Minimal config is more complex, but has more posibilities.

Last edited by Marek Bartoš (2022-09-05 16:26)

jeremy
Member | 46
+
0
-

Marek Bartoš wrote:

Btw, what is your usecase? We needed this for eshop, where B2B and B2C users have different functionalities on public site and admin needed to test them easily both.

Eventually, you could use similar solution (I created) which solves this problem out of the box, but API, even being quite similar with nette/security, is currently incompatible. It's called orisai/auth (with nette-auth as a Nette di+Tracy integration). Minimal config is more complex, but has more posibilities.

Thanks for the reply! My use case will actually depend on what I need my system to do. That's why I want to have my admin user separated from frontend. I want to have a basic backend system that I can extend by whatever “addon” I need for my projects. Whether it's an eshop, blog or something else. I used to work with wordpress for some time but I was never really a fan of the overall experience, then I moved to REDAXO which is a decent simple CMS but the problem is that the documentation is only in german so overtime it just became a headache to translate stuff that I needed.

So now here I am trying to create something of my own.

Last edited by jeremy (2022-09-05 17:14)

materix
Member | 66
+
0
-

@jeremy Have you taken a look at processwire.com?