Open ponasromas opened 6 years ago
Isn’t this normal browser behavior (instead of something specific to this library)?
Can you log in to two separate accounts with Facebook or Google, for example?
The only way to have to separate sessions should be for your browser to manage two separate cookie jars, e.g. one normal browsing window and one “private browsing” window.
Gmail allows multi-session logins. But in our case I see another problem - it's not possible to identify that I'am logged in as admin to a user account. This leads to a problem:
Could you offer any solution to solve this? It would be perfect to identify login type as "impersonated" login.
I hope issue is clear enough :)
That multi-session capability is not the norm, though, wouldn’t you agree?
In any case, this cannot be done without an account switcher. So that’s something that has to go into your UI, not into this library. You could provide an account switcher in HTML/JavaScript and swap the cookies as needed, or do it on the server to avoid having to provide JavaScript with access to your cookies.
Firefox recently introduced Multi-Account Containers specifically to address the multi-account issue (and other issues related to the one big cookie jar shared by all sites).
The other (but related) issue that you’ve brought up now, however, is definitely something that is related to this library.
In order to test a preliminary implementation, could you go into the vendor
directory in your project directory, open the folder for this library, and edit the Administration
class? In method logInAsUserByColumnValue
, before line 567, could you add the following?
$_SESSION['impersonator'] = [];
$_SESSION['impersonator'][self::SESSION_FIELD_LOGGED_IN] = $_SESSION[self::SESSION_FIELD_LOGGED_IN];
$_SESSION['impersonator'][self::SESSION_FIELD_USER_ID] = $_SESSION[self::SESSION_FIELD_USER_ID];
$_SESSION['impersonator'][self::SESSION_FIELD_EMAIL] = $_SESSION[self::SESSION_FIELD_EMAIL];
$_SESSION['impersonator'][self::SESSION_FIELD_USERNAME] = $_SESSION[self::SESSION_FIELD_USERNAME];
$_SESSION['impersonator'][self::SESSION_FIELD_STATUS] = $_SESSION[self::SESSION_FIELD_STATUS];
$_SESSION['impersonator'][self::SESSION_FIELD_ROLES] = $_SESSION[self::SESSION_FIELD_ROLES];
$_SESSION['impersonator'][self::SESSION_FIELD_FORCE_LOGOUT] = $_SESSION[self::SESSION_FIELD_FORCE_LOGOUT];
$_SESSION['impersonator'][self::SESSION_FIELD_REMEMBERED] = $_SESSION[self::SESSION_FIELD_REMEMBERED];
$_SESSION['impersonator'][self::SESSION_FIELD_LAST_RESYNC] = $_SESSION[self::SESSION_FIELD_LAST_RESYNC];
With that done, you could add the following two new methods into the UserManager
class:
public function canLeaveImpersonation() {
return isset($_SESSION) && isset($_SESSION['impersonator']) && isset($_SESSION['impersonator'][self::SESSION_FIELD_LOGGED_IN]) && $_SESSION['impersonator'][self::SESSION_FIELD_LOGGED_IN] === true;
}
public function leaveImpersonation() {
if ($this->canLeaveImpersonation()) {
$_SESSION[self::SESSION_FIELD_LOGGED_IN] = $_SESSION['impersonator'][self::SESSION_FIELD_LOGGED_IN];
$_SESSION[self::SESSION_FIELD_USER_ID] = $_SESSION['impersonator'][self::SESSION_FIELD_USER_ID];
$_SESSION[self::SESSION_FIELD_EMAIL] = $_SESSION['impersonator'][self::SESSION_FIELD_EMAIL];
$_SESSION[self::SESSION_FIELD_USERNAME] = $_SESSION['impersonator'][self::SESSION_FIELD_USERNAME];
$_SESSION[self::SESSION_FIELD_STATUS] = $_SESSION['impersonator'][self::SESSION_FIELD_STATUS];
$_SESSION[self::SESSION_FIELD_ROLES] = $_SESSION['impersonator'][self::SESSION_FIELD_ROLES];
$_SESSION[self::SESSION_FIELD_FORCE_LOGOUT] = $_SESSION['impersonator'][self::SESSION_FIELD_FORCE_LOGOUT];
$_SESSION[self::SESSION_FIELD_REMEMBERED] = $_SESSION['impersonator'][self::SESSION_FIELD_REMEMBERED];
$_SESSION[self::SESSION_FIELD_LAST_RESYNC] = $_SESSION['impersonator'][self::SESSION_FIELD_LAST_RESYNC];
unset($_SESSION['impersonator']);
}
}
Finally, you’d be able to call these two new methods on the Auth
instance as with all the other methods.
Let me know if that works for you.
Function "canLeaveImpersonation()" works and returns true. But function "leaveImpersonation()" does nothing at all. I use login with username. Do I understand correctly: function "canLeaveImpersonation" checks whatever user was logged in from impersonation function?
If yes, than it does not work accurately, because it returns "true" even if logged in directly.
Thanks!
Did you put the new code into the correct files and places? The first block of code goes into the Administration
class while the second goes into the UserManager
class.
You are right, $_SESSION['impersonator']
should only be set if you have signed in as an administrator (impersonating a given user) and thus canLeaveImpersonation
should also only return true
if you have done that.
Can you check the value of $_SESSION['impersonator']
after logging in as a normal user (it should not be set or should be null
) and after impersonating a user from the administration interface (it should be set and should be non-null
)?
Did you have a chance to try the additional notes and potential fixes?
Hey Ocram, unfortunately no. I deployed my beta version of system to production and now other things matter more than this. But non-the-less, this function would be handy to have in main version of library. Thank you for your time and effort to help!
In any case, this cannot be done without an account switcher. So that’s something that has to go into your UI, not into this library. You could provide an account switcher in HTML/JavaScript and swap the cookies as needed, or do it on the server to avoid having to provide JavaScript with access to your cookies.
Hi, I just wanted to add that Google's Gmail defines which account you will be using via url: https://mail.google.com/mail/u/0/
. This allows you to open a tab with a specific account i.e. from a bookmark. I do not know of other services that do this.
However, this is not something that would need to be handled by the library specifically. I believe it could be implemented quite easily as a layer over-top of the current library.
Hello,
I'am facing issue when impersonating user:
Problem: it is not possible to have 2 separate sessions: one for user A and for user B. Maybe I missing something?