Reputation: 2455
getting in another discussion at work here about how to authenticate, or more likely. Who should authenticate a user.
Given the following code examples:
<?php
class User {
public function isValid($username, $password) {
//Logic to check if username/password match
$this->setId($id);
}
}
vs.
<?php
class Auth {
public function isValid($username, $password) {
//Logic to check if username/password match
$user = new User;
$user->setId($id);
return $user;
}
}
I personnaly give the following example why in this case #1 is bad: If a user is allowed to authenticate themself. And they would walk into a movie theater. They can just walk into any movie. Just saying to themselves they are valid.
Where the second example has an external object checking for the validity of the user. Thus being more "oop"
Mind you I have no education in OOP programming and this is probably something I read back in '08 or '09 when I started coding :) I hope some people here know what I mean and can then explain what are the good/bad practices here.
Thanks in progress
Upvotes: 1
Views: 246
Reputation: 13737
You are right in that it is not very common for a person to authenticate himself when eg going to a movie. In you're argument with your co-workers you may want to generalize this:
Who is responsible for authenticating a user?
This is a question you can ask yourself every time you seem stuck on a design question. I'm not saying it's the one rule that will answer all your questions, but it clears troubled vision in a lot of situations and your question is an excellent example.
You also may want to read this text:
http://lizkeogh.com/2009/07/01/pixie-driven-development/
Upvotes: 0
Reputation: 316939
The logic should not be on the User for two reasons:
Now, you could decouple the authentication logic (1) and work on object members (2) by doing
class User …
public function authenticate(Authenticable $adapter)
{
$this->isAuthenticated = $adapter->authenticate(
array(
'username' => $this->username,
'password' => $this->password,
)
);
}
}
but this bears the question why (and how) password should be stored on the User at all. You surely dont want to have the cleartext there. And hashing the password is not the responsibility of the User in my opinion. In fact, you cannot hash it in the User if you dont also add the salt to the User and that's something I would not think of a typical User property. You could hash the password to rehash it with a salt in the $adapter, but that is only curing symptoms. In OOP, Object Methods should operate on the members of an object. But if password shouldnt be a member of the User in the first place, the method using it shouldn't be on User either (cohesion).
Needless to say, if you are using ActiveRecord, you will likely have something like the above or have the authentication method as a static method on the User that will then return an instance. Personally, I dont like AR and static methods, so I'd go with a separate Authentication Service class that returns Users for me.
Upvotes: 2
Reputation: 2158
Your User
object would be a model for a user profile, holding details such as username, password, email, etc. However, you can theoretically have a profile on a site without linking that to a login (perhaps there is only one master administrator who can edit profiles).
Your Auth
class would handle the login check as I imagine that would also deal with setting and removing user sessions, which are separate from the actual user profile.
User
= Model for user dataAuth
= Logic for authenticationThink of it this way, if you decided to change how your profile authentication works (perhaps removing your own login process and replacing it with Twitter OAuth), separating your authentication logic from your user profile could make this easier.
Upvotes: 1