phpsword / sword-bundle

Modern WordPress development with Symfony
https://getsword.com
MIT License
125 stars 4 forks source link

Question: How to get current user ? #5

Closed Romaixn closed 1 year ago

Romaixn commented 2 years ago

It is said that it is possible to have a synchronization of accounts from WordPress to Symfony, how to recover the current user and use the management of Symfony roles?

williarin commented 2 years ago

In Symfony you can use Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorageInterface to retrieve the user:

$user = $this->tokenStorage->getToken()->getUser();

Or from an AbtractController directly call:

$user = $this->getUser();

This will give you a \Sword\SwordBundle\Security\User instance which is mapped to the wp_users table and with a capabilities property containing all WordPress capabilities for this role.

It's not meant to be used with Symfony users injected into WordPress, but the opposite.

Romaixn commented 2 years ago

I just tested by being logged in as administrator to my WordPress and using the $this->getUser() in a Symfony controller but null was returned to me.. Is there anything more to do? Migrations or something else?

williarin commented 2 years ago

Indeed I just had the problem too. It seems that the Symfony session isn't well synchronized with WordPress. Right after login it works, then after a while it doesn't work anymore...

Romaixn commented 1 year ago

Hi ! Are you using that : https://github.com/phpsword/sword-bundle/blob/ea77394665ba973efafc5e33b9eb97aec1abe1cf/src/Loader/WordpressLoader.php#L85 for login user to Symfony ? wp-login.php don't raise exception, so I think this line is never executed..

And wordpressLogin / wordPressPassword is never defined here https://github.com/phpsword/sword-bundle/blob/ea77394665ba973efafc5e33b9eb97aec1abe1cf/src/Security/UserAuthenticator.php#L129

williarin commented 1 year ago

It's a workaround I found to log in both WordPress and Symfony.

  1. User logs in WordPress, Sword intercepts the login then throws an exception (because WordPress redirects after login so we need to kill the request and let Symfony keep it). This is when $this->getAuthResponse is called for the first time.
  2. Now the user is logged in WordPress but not Symfony, so Symfony stores the user data in a flash bag and redirects to the same page to let UserAuthenticator authenticate Symfony.
  3. UserAuthenticator finds the flash bag variables after the first redirect, and fills $this->wordpressUsername etc. Then proceed to Symfony authentication. It makes a second redirect when done.

I don't know if there's a way to authenticate Symfony before the first redirect as it's already beyond the firewall as I understand it.

The problem seems to be that the login session differs between Symfony and WordPress, as Symfony will logout the user after a while, while WordPress user stays logged in.

loicrey commented 1 year ago

What if you query the wordpress_logged_in_ cookie or the wp_get_current_user() function on each request with an event or a firewall ? Maybe it's not the most secure or optimized but this is my temporary workaround to deal with cross authentication between Wordpress and Symfony.

Also cookie method can probably solve cross authentication if Wordpress is on another subdomain (in my case, I will only use Wordpress as a CMS for posts, authors and taxonomies)