Implementing a Generalized Site User Service
Identification vs. Authentication
I want to start by making a distinction between identification and authentication. The way I'm using the terms, identification tells me "this is you" - although I may have no idea who "you" are. Authentication associated an identified request to a persistent instance of an object (usually a user) so I know it's Fred Jones of 22 Acacia Avenue who is interested in Photography and has bought from us 12 times over the last 3 years.
Approaching the API
Three things could happen when trying to get a site user for a given request. I could not have a token in which case I need to get a new site user, I could have a valid token in which case I should get the associated site user along with any associated data (shopping cart, user information if authenticated, etc.) or I could have an invalid or expired token in which case I should get a new site user.
It seems like the simplest approach to this would be a SiteUser = SiteUserService.getSiteUser(SessionToken:UUID) with the UUID being optional. In all three cases I'll get a site user which I can then interrogate as to whether it isAuthenticated() or hasCart() or whatever else the controller or the model might need to know.
So, how should getSiteUser() work? It should take advantage of the real session scope where it exists and the pseudo-session scope where it doesn't. Seems to me like this is a perfect use case for a SessionFacade singleton to take care of this seamlessly as it wouldn't surprise me if I'd need to have this kind of functionality elsewhere.
So, what would that give us? Right now I've just got:
<cfargument name="SessionToken" type="string" required="false" default="" hint="The token to uniquely identify the site user between requests.">
<cfscript>
var SiteUser = "";
If (Len(SessionFacade.get(SessionToken, "UserID")) GT 0)
{SiteUser = getByID(SessionFacade.get(SessionToken, "UserID"));}
Else
{SiteUser = new();};
// Give the site user the token to access its session scope SiteUser.set("SessionToken", SessionToken);
</cfscript>
<cfreturn SiteUser>
</cffunction>
It meets my needs for now. I don't love passing the SessionToken into every request to the session facade, but most of my model calls against the session will be encapsulated within the SiteUser object so I can encapsulate this in a "SiteUser.sessionGet()" method if I need to, and if I chose to refactor this it shouldn't be too hard to do, so now I'm going to get back to the rest of my model API which is actually what I need to rewrite and rewire today.
Thoughts?


There are no comments for this entry.
[Add Comment]