You can skip this - these are my thoughts on the problem
In Front Controller (344) Fowler writes "In a complex Web site there are many similar things you need to do when handling a request. These things include security, internationalization, and providing particular views for certain users." The front controller, however, is for handling all requests to a web site, so stuck wondering where Authentication and Session management fit into the mix.
The most tricky thing is that certain domain objects and almost all templates must be aware who is currently logged in and what rights they have.
Previously, I put a "User" object inside the registry. This contained the username, userid, and userrights. Whenever it was needed, it was called from the Registry, and then the data it contained operated on. The thing was, when you determined the correct user to load, and whether or not the user was authenticated, and whether or not a session should be started, they where all stuck in Transaction style functions. No good for a Domain Model.
So, these are a different kind of object. They're not persisted in the database, and they do things that affect the presentation, but they still contain business logic.
Well, here we go:
Read here
authenticate() - You call this function and everything magically happens (including the user object getting registered)
login() / logout() / session() / remember() - These perform various authentication actions
assertLogin() / assertLogout() ... - This checks the environment and determines whether or not we should perform the actions (sorta like a Front Controller...)
validateLogin() / validateSession() - Determine whether or not the attempt by the user was correct: if not, then don't do the actual action
destroySession() - destroy a stale or logged out session
createSession() - create a new session
cacheSession() - send http headers to override PHP's no cache to "private"
How should I factor these functions into their own domain object classes?
The place of Authentication in Domain Model
Moderator: General Moderators
- Ambush Commander
- DevNet Master
- Posts: 3698
- Joined: Mon Oct 25, 2004 9:29 pm
- Location: New Jersey, US
- Maugrim_The_Reaper
- DevNet Master
- Posts: 2704
- Joined: Tue Nov 02, 2004 5:43 am
- Location: Ireland
It seems that both belong right at home in the Front Controller. I can't see any dedicated place to put them, unless you push the actual processes into their own distinct classes, and simply pass the relevant method call from the FC. The front controller as well as handling requests, and their mapping to the model layer, does allow centralisation of these once off "setup" like procedures.The front controller, however, is for handling all requests to a web site, so stuck wondering where Authentication and Session management fit into the mix.
And the problem is that what I stated as a solution breaks the separation by mixing DB calls, business logic, etc. into a single object?The most tricky thing is that certain domain objects and almost all templates must be aware who is currently logged in and what rights they have.
The greatest divorcement can be done using an Application Controller (which will use State to determine what actions are executed, and what Views are called upon). To be honest that seems overkill for handling a simple isLoggedin/notLoggedin decision. You could of course combine those authentication flags with some sort of ACL/Permission system which would operate directly in the Model/View layers... Either way this stuff is going to have to be shared between all layers...
Maybe divorce User Data from everything else? I would keep a separate User and UserACL class.Previously, I put a "User" object inside the registry. This contained the username, userid, and userrights. Whenever it was needed, it was called from the Registry, and then the data it contained operated on. The thing was, when you determined the correct user to load, and whether or not the user was authenticated, and whether or not a session should be started, they where all stuck in Transaction style functions. No good for a Domain Model.
I could be reading you completely wrong, but I'd run a sequenced process.
1. Authenticate User (sets a Session/State flag)
2. Create User Object (just a data holder really) based on the selection of user details authenticated (id, name, pass) - id being obvious for a DB call.
3. Create an ACL class passing User as parameter
4. Register objects as required.
Both User and ACL would have separated Data Access classes. The Authenticate process would make a short DB call to grab the attempted login users name/pass and id. Full User data only collated after authentication. ACL sort of joins Authentication and Authorisation (permissions/rights) into one object to be passed to Model layer (of course Views may require them also - unless you set up all View variables in a Model object prior to calling the View, e.g. by using an intermediary ViewData or similar object...)
Nothing really "bad" with the above. Authentication, User, UserACL, SessionManagement, StateData and Response are all classes I could see factoring into.authenticate() - You call this function and everything magically happens (including the user object getting registered)
login() / logout() / session() / remember() - These perform various authentication actions
assertLogin() / assertLogout() ... - This checks the environment and determines whether or not we should perform the actions (sorta like a Front Controller...)
validateLogin() / validateSession() - Determine whether or not the attempt by the user was correct: if not, then don't do the actual action
destroySession() - destroy a stale or logged out session
createSession() - create a new session
cacheSession() - send http headers to override PHP's no cache to "private"
Authentication: performs basic authentication, is passed the Request (login details - or filtered version thereof), and UserTemp (basic user details for authentication checks). It would return either void, or create a Session/State flag using StateData maybe.
User: After authentication is passed, the full User data can be fetched and object registered.
UserACL: fetch access rights data and register object. User as a parameter.
SessionManagement: basic session functions as noted perhaps.
StateData: a fancy name for a glorified sub-array, e.g. $_SESSION['_statedata']. Used for data which should be persisted across requests and specific to application flow. e.g. authentication flags.
Response: handles header/content/redirect setting (Front Controller should have final say in outputting everything). A Response object also allows centalised implementation of say output compression.
Actually, I think Authentication is Model layer, setup of ACL controller layer, and use of ACL model layer. I assume the FC would only validate the original Authentication, setup access rights, and allows individual actions (say Command objects) check user rights.
- Maugrim_The_Reaper
- DevNet Master
- Posts: 2704
- Joined: Tue Nov 02, 2004 5:43 am
- Location: Ireland