I'm creating an authentication system for a group of websites. The problem is that I have to use a pre-existing Database, which has a users table already full of entries, and that one user can have several accounts. Basically, a user has one account per website he has access to (it's not the best way to do this, but I can't change it). Each account is represented by an entry in the users table, with login, password, name... and the important field: website_id. This field tells the system what website that account has access to.
The big problem is that some users with more than one account have the exact same login/password information for all of them. For example, one user has 3 accounts:
- account1: login = charly / pwd = 1234 / name = Charles ... website_id = 1
- account2: login = charly / pwd = 1234 / name = Charles ... website_id = 2
- account3: login = charly / pwd = 1234 / name = Charles ... website_id = 3
So if he goes to the website that has id = 2 and uses those credentials, he's granted access. If he goes to the website that has id = 4, he's denied access.
My problem is that since CakePHP does the login automatically, when a user tries to login, CakePHP checks only the first entry in the Database that matches the login/password submited in the form. So if a user is currently in the website with website_id = 3 and tries to login, Cake finds the first e开发者_如何学Gontry (account1), compares its website_id (1 in this case) to the current website's id (3), and since they're different, the access is not granted, but it should. _Please note that the comparison of the website_id vs the account's website_id is already being made manually in the login() function_.
This how the login() function looks like now:
function login() {
$userInfo = $this->Auth->user();
if ( isset($userInfo) ) {
if ($userInfo['User']['website_id'] == $this->website_id) {
//Users gets access to a website that he has an account for
}
else {
//User is denied access because his account is not registered for the current website
$this->Session->destroy();
$this->Session->setFlash(__('You don't have access to this website', true));
$this->redirect($this->Auth->logout());
}
}
}
What I would like is to be able to manually authorize the access to the current website by using the login/password submitted by the user to manually search in the users table, and if I find a match in one of the user accounts, grant the access, or otherwise deny access. To sum up, avoid all the automagic of Auth's component.
If the Auth component's login method fails, control is transferred back to the custom login action (e.g. UsersController::login()
). I've used this to authenticate using either username or email address, but it could be easily adapted for this purpose. Same idea, different criteria. I offered what I think is a reasonably thorough response (with code) to a similar question. It may help you as well.
精彩评论