I have the following tables:
People
Users
Emails
The user's password is stored in the Users table and I want them to use their default email address which is stored in the Emails table to authenticate. The email is indicated as their default by a boolean column in the Emails table.
How do I use CakePHP's Authentication component in this setup?
I think you shoulnd't split the info in separate tables. Put everything in your Users table, and then make one-to-one relationships.
Anyway, if you want to do it this way you should override the login() method in the UsersController.
Here you have an example: http://bakery.cakephp.org/articles/SeanCallan/2007/04/17/simple-form-authentication-in-1-2-x-x
This is the method you need to override:
http://api13.cakephp.org/class/auth-component#method-AuthComponentlogin
EDIT:
Make your auth data depends on Users only. I mean, put email, username (if you have one), and password there. After that, if you have, for example, People table to record other info (first name, addres, phone, etc), make an one-to-one relationship with that table. If you have your Customer table, and your customer can be users, make a one-to-one relationship.
I ran into this troubles some time ago, and was useful to solve it as Django do, and is with this one-to-one solution.
This answer should be enough evidence that you will not be able to use multiple models for your Auth component. It only supports a string, not an array. But if you keep reading, there might be a work around for you.
Create a /app/Controller/Component/Auth/MyFormAuthenticate.php file, and setup Auth to use MyForm instead of Form for authentication.
In this file include the authenticate function and the _findUser function.
You then need to override the _findUser function to suit your needs.
Thanks to Ceeram on the CakePHP freenode channel for this solution.
Related
I'm working a site for invoicing and inventory, and I need two different kinds of Authentication, one for clients and other one for users (sellers, administrator). I know it would be easier to have a single table Users with a field like user_type, instead of having Users and Clients but I need this two tables individually because they interact each other and also have differents behaviors. What do you think I should do for an efficient authentication?
I think what you want is permission groups. This way you can add a group called clients and one as administrators or sales. I would look # Sentry by Cartalyst. I use this to manage 13 groups. This also has the ability manage permissions and write conditional statements on permissions.
No idea what your software does but it looks like you need to do some reading on pivot tables.
My guess is that you have "clients", "Users", and "Invoices"? and need each invoice to have a client and a user? Maybe several of either?
All of you members, client or user, in the same table. Make sure to give them all a 'user id' of some sort.
'Invoice' table, same as the last two.
Pivot table would be member_to_invoice. This would be a many to many pivot (i think) and would simply have (invoice_id, client_id, user_id).
This would give each invoice a member and a user. The drawback of this would be that a member type is only set by the invoice. So there wouldn't be a way to have a client log in that was different then a users. Though that might not be a drawback depending on what the system does.
You could set it up the other way as well with another table 'member_type' and pivot that off the member table. This would give you separation in the member types. Then you wouldn't really need the member_to_invoice pivot unless you needed multiple users or clients attached to a single invoice.
I have used this tutorial for creating my user login in Laravel: Laravel Authentication Essentials. So I have a SessionController that contains the methods create, store and destroy, for showing the form, logging in and out respectively.
But there is no model in this tutorial, the validation and Auth::attempt is in the controller. And that doesn't feel right. I can not create a Session model, since the Session class already exists.
Should I put the login/out logic in the User model, or is there another way to do this that complies with the MVC architectural pattern?
First, remember (or know) that you can change everything in Laravel. If you need a Session model using a sessions table, go to app/config/session.php and change the Laravel sessions table to laravel_sessions:
'table' => 'laravel_sessions',
People are doing things differently these days, methods are improving on a daily basis and the way you do your code must be confortable to you. If you feel it is not right the way you are seeing people doing it, change it, Laravel give you the power to change and do things your way. And if you feel you just found a better way of doing it, share it.
This is a 2013 video and today Jeffrey is doing authentication in a completly different way. Sign up for a Laracasts account and take the full Build a Larabook video series to see how he's doing it now.
There's no Session model in this tutorial because he's not storing sessions (successful logins) in a sessions table.
In the tutorial he never touches the User model, so there is no login in the user model. The only thing he's using to do authentication is Auth::attempt(), a Laravel facade method which uses internally the user model (M), to find a user and check if the password matches. He's working with a Session controller (C) and everything related to login (or sign in) and showing login views (V) is done inside that particular controller.
If it is easier to you, you can rename SessionsController to LoginController, I, myself, don't really like the Sessions name for login, but that's a matter of taste not code correctness.
That being said I don't see an MVC (or whatever name people like to call it this week) problem in that video.
EDIT Answering the comment:
The purpose of the model is towards data, no data, no model. In the context of Laravel and a database management system, yes, no table, no model. In the context, for instance, of a client-server API, your server API (Laravel, Rails...) will provide data for your client model (Angular, EmberJS...), so, there will be no table directly related to the client model, but still a model.
But in that particular case you are accessing a model, the user model, via a service, the Authentication service.
I'm hoping to use Ion Auth for a Codeigniter application, but I'm unsure of exactly how to structure the tables appropriately. Basically, I have a few different types of users each with different attributes. How would one build this out with just a single meta table?
Some ideas were offered here ( Create user roles and profiles in Codeigniter using Ion Auth ) but none seem particularly elegant or ideal. Is there a a better way? Can I easily work with multiple meta tables (e.g. meta_type1, meta_type2, etc.) somehow?
A related issue pertains to the "identity" config parameter for login etc. How could I have the identity be email for one user type, and username for another?
Thanks in advance for any tips/advice/ideas
Ion Auth code is really clean and organized.
You can easily hack the login process to accept both username or email. Even better, you can fork the repo on GitHub and make the $config['identity'] variable accept both string or array, and act according to that. And send a pull request! :-)
Regarding meta data for users: I would definitely use a single table to handle users metadata. You can put several columns and set to null in case some user type doesn't need them.
Hope my ideas help! Good luck and happy coding.
I also meet the same problem as you. And i found codeigniter authentication library alternative that could solve the problem. Flexi Auth seems can handle "multiple extra meta table" for different user groups.
I have a domain for users that connects to my user table, which includes information like username, first name, and last name.
Then I have a domain for emails, that connects to the email table because a user can have more than one email. The email table consists of a fk to connect the user with their emails, and other fields like address, status, etc.
Should I have different domains for the separate tables, but combine functions, that call the domains, in the models? Or maybe you can but it's not best practice.
I am new to this MVC thing and it's hurting my brain right now. Maybe, it just someone hasn't explained it well enough.
Question: when you mention having a "Domain", are you referring to a User model, and an Email model? or to the design pattern?
Also, initially (but depends on your application) having the email database logic inside the users model is more logical (to me), since I don't think you are going to add email addresses without creating a user. That is, the email model really depends on the user model, and perhaps only on the user model, so maybe they should be combined?
The way I would do it:
Put all the database logic inside the models which I assume is the way you have done it.
Create a library or class to place the business logic of the application that concerns users. (For example, uploading an image, or connecting to a web service, should not be in the model if you follow the standard that CodeIgniter models should only contain database logic, so that's why I create another class to handle those cases)
Now, when you want to create an user, you just inject the models in the library (you could do this at the controller level), and call your abstract method create_user()
class Users extends Controller {
public function create() {
// these could be in the constructor!
$this->load->model('users');
$this->load->library('users_logic');
$this->users_logic->set_model($this->users);
// and/or: $this->users_logic->set_email_model($this->email_model);
if ($this->input->post('name')) {
$this->users_logic->create();
}
}
}
That's kinda vague so here's the meaty stuff:
I have seen authentication systems that do one of the following
have a separate role table for each roles, and a separate permissions table, all users in one table
have a separate table for administrators
there's a lot that I have missed, I know. But what I'm trying to really ask is:
How should I design my database in a website that I have a lot of kinds of users and each with different access?
How will I make it so that my script is flexible enough if I decide to add another type of user with another type of permissions?
I currently have a User class and am planning to make my Administrator class which extends that User class. Or is that a bit of an overkill when I can have them all in a single class and just assign necessary permissions?
you can have tables -
user (user_id, name ...)
permission (perm_id, name, desc)
role (role_id, title)
user_role (user_id, role_id)
user_permission (user_id, perm_id)
role_permission (role_id, perm_id)
This way you can have as many roles in the system as you require, and you have both role level permissions, user level permissions.
you can add an additional level of abstraction. basically you add a table in your database to manage user groups, and assign group permissions to those groups. different users can have multiple groups.
this way you can quickly change permissions to a predefined set of rules, without needing to change every user separately. you can also change the permissions for a group of users at once
I think you need to think about several concepts here. The first would be an access control list (ACL) and then second would be authentication.
In an ACL, you define resources, which are objects that you want to restrict access to and roles, which are objects that may request access to a resource.
The way I implement my ACL, is using Zend_Acl. I have a table called user_roles
user_roles('user_role_id', 'name', 'permissions', 'parent_role_id')`
I also have a table called user_role_maps that maps a user's ID to a user role ID. (You could just have this as a column on the user table, but that just depends on how you feel about normalisation ;-) .) I can then construct my Zend_Acl object from this table and then, when a user is authenticated, I can determine which resources they have permission to and what actions they can perform on a resource. (A resource implements Zend_Acl_Resource_Interface so it is identifiable by Zend_Acl as a resource.
As for authentication, this is a simpler concept (in my opinion), you've probably already figured out some form of token matching authentication system yourself. The crucial aspect is using the authenticated user's ID to determine their role. The Zend Framework also provides a package for this in Zend_Auth.
I've used a lot of Zend Framework recommendations here, the reason for this is that their packages have very few dependencies on other packages, making it quite simple to plug components in. I'm sure other frameworks provide ACL packages that you could use, or roll out your own if you have the time and understanding.
Good Luck.