Sometimes dealing with MODX user authentication can be tricky. You've probably heard people tell you to view the front end from another browser when testing. I've assembled here a few pointers to keep in mind.
1) Context matters! By default you have the "mgr" context and the "web" context. Being logged in to one does NOT mean you are logged in to the other. Think of each context as a completely different website.
2) You can be "in" different contexts while logged in to other contexts. When you log in to the manager, then view your home page, you would be authenticated (logged in) to the "mgr" context, but actually browsing the "web" context.
3) Permissions are different than authentication. The administrator super user automatically has "permission" to view anything, but this does not mean he is automatically "logged in" to anything. This means that even though your admin "has permissions", if they are not also "logged in", they can still show weird behavior on the front end, like being blocked from content even though they are a super user. If you build your user auth model such that you test for authentication before showing content, then even your sudo user admin will be blocked.
For example, if you test if a user is authenticated, and then hide a menu if they are not, then even your admin would not see the menu, regardless if they are a sudo user, because they are not authenticated.
4) There are a handful of tests you can run in your snippets to test user authentication, regardless of their permissions or groups. They are:
$user = $modx->getUser(); // Grab current user
// This returns the context the user is currently in
// Keep in mind that even if you are admin, logged in to Manager, if you view your home page, you'd be in "web" context
$modx->context->get('key');
// This outputs true or false depending on whether the user is logged in to the active/current context
$user->hasSessionContext($output['Current Context']) ? "True" : "False";
// This is basically the same as above, by telling you if the user is authenticated in the current context
$user->isAuthenticated($output['Current Context']) ? "True" : "False";
// NOTE: The only difference I can find between "hasSessionContext" and isAuthenticated is that isAuthenticated accepts a single context to test, and assumes "web" if omitted, while hasSessionContext can accept one or more contexts to test in case you need to test multiple contexts in some scenarios.
// Regardless of what context you are in, which context(s) is the user actually authenticated in?
// Notice the 's' on the end. You can be authenticated in more than one context, and this returns an array
$user->getSessionContexts();
The above tests can tell you whether a user is IN a context, or HAS a context (authenticated in it), and which contexts they currently are authenticated in. It has nothing to do with what user groups or permissions they might have beyond that.
I have put together a simple little snippet using the tests above that you can stick in any page of your site to give you this information about the current user.
Create a new snippet called "UserTest" or whatever you want, and paste this code:
<?php
$user = $modx->getUser();
$output['Username'] = $user->get("username");
$output['Current Context'] = $modx->context->get('key');
$output['Has current context?'] = $user->hasSessionContext($output['Current Context']) ? "True" : "False";
$output['Is authenticated in current context?'] = $user->isAuthenticated($output['Current Context']) ? "True" : "False";
$output['What context(s) do we have?'] = $user->getSessionContexts();
return "<pre>" . print_r($output, true) . "</pre>";
Save the snippet, and then on any random page you feel like testing this out on, put the snippet call [[UserTest]]. Here is what my output says when I'm logged in to the manager, but viewing the front-end with my admin user:
Array
(
[Username] => admin
[Current Context] => web
[Has current context?] => False
[Is authenticated in current context?] => False
[What context(s) do we have?] => Array
(
[mgr] => 1
)
)
Note the current context is "web" and I do NOT have this context, and yet I DO have the "mgr" context.
Here is the output when I log in to BOTH my manager, AND as a normal user (same username/pass, logged in to both sides):
Array
(
[Username] => admin
[Current Context] => web
[Has current context?] => True
[Is authenticated in current context?] => True
[What context(s) do we have?] => Array
(
[mgr] => 1
[web] => 1
)
)
Now you can see the current context is still "web", but this time I am authenticated in web. Notice my one user is authenticated in TWO contexts. I literally had to log in with my user/pass TWICE to accomplish this.
You might be asking, can I log in just once and still have more than one context then? The answer is, this is not built in to MODX to allow this. If you wanted a type of "single sign on" across all your different contexts, then you would have to program this yourself. There are a couple functions to look into called "addSessionContext" and "removeSessionContext" to add and remove additional contexts from a user. It might be more complex than that, but it gives you an idea of where to start looking.
Now to make matters worse, if you create a section of your site that is "protected" unless a user is logged in, you would use resource groups to do this. So let's say you have a page called "The Secret List" and only the resource group "members" can see it.
In this scenario, your admin user is a sudo user, so resource groups are no match for him, he will be able to view this page even though you've protected it from every other user. This means your admin user will show up in this context, and NOT be authenticated, but still see the page.
The tricky part is this, let's say that in your page is a menu for users to manage their profiles or payment information or something. In order to show this menu, you use a snippet and the snippet has this code:
if ($modx->user->hasSessionContext($modx->context->get('key')))
return "THE MENU STUFF";
else
return "NO MENU";
What will happen here is that your admin user can view The Secret Page just fine, but will find the menu is missing due to the explicit test of authentication. In the one case, admin has rights to view the page and is not blocked, but in your snippet you are testing only for authentication, not groups/permissions or sudo abilities. Since admin is not authenticated, but has persmission via MODX itself, he will see the page and all its content, but NOT the menu which you explicitly test user auth to show.
This is why MODX experts warn you about being logged in as admin, and also viewing the front end with the same browser. As your website becomes more complex and there are user roles, permissions, groups, contexts, auth issues, and snippets like above which test for certain conditions, your admin user will see "odd" behavior. They might see some stuff and not other stuff, page redirects based on permissions may not work right, and other tests may seem "off" or even broken.
So bottom line. Once you get an idea of how resource groups and permissions work, and some of the auth issues above, it makes a lot more sense to test with multiple browsers.
Hope this helps!
[ed. note: vigilante last edited this post 11 years, 10 months ago.]