I have these tables in the database :
user:
- email
- lastname
- firstname
- password
userType1:
- fkUser
- specialCol1
- specialCol2
userType2:
- fkUser
- specialCol1
- specialCol2
I've made the Symfony2 authentification service working with user table but i want to store in the session (or in other place manage by the authentication) the associated object: userType1 or userType2.
Futhermore, i want to redirect the user to its account depending on his type.
So my questions :
How to make treatement after submitting authentification form ? (to determine which type of user it is)
How to tell to Symfony to manage an other object (the user type) in the authentification context ?
Have a look at the cookbook-entry How to load Security Users from the Database. The sections "Authenticating Someone with a Custom Entity Provider" and "Managing Roles in the Database" might be helpful.
I had a similar problem with an authentication-procedure where a User and their Tenant-memberships were required. I built a custom provider which basically looks like the one from the cookbook. When serializing the User I only use certain field (id, username, email) and the rest of the data is fetched via the provider's refreshUser(), where again the User and their relationships are fetched via QueryBuilder. I had the problem, that when serializing the User in the session, the relationships were "lost" otherwise and I had to refetch the User all the time.
After that it's basically what #BenjaminPaap wrote. You retrieve the user as described in the documentation and get the user types, etc.
If you want to redirect the user to a certain target depending on their userType, you might want to look at "How to create a custom UserProvider". The Listener provides everything you need to redirect the user according to their type right after login.
Related
First off, I am new to Symfony, so I don't know the exact functionality of bundles like FOSUserBundle etc., as well as the terminology.
I am looking for a way to use the Symfony security component in a way that enables me to decouple a user's login credentials (say, a login name and a password, maybe the roles) from the actual user meta data (like first name, last name, groups, birth date, etc.).
The idea is that a user can login with different sets of login name/password and still be recognized as the same user (in the end that means, getting the same User object).
To me, this comes especially handy in combination with multiple authentication providers. For example, if I wanted to enable my users to login via an OAuth2 service as an alternative to logging in with their locally-hosted login name/password-combination (like StackExchange does, for instance), how would I do that?
I have read multiple pages of documentation of Symfony, e.g.:
https://symfony.com/doc/current/security.html
https://symfony.com/doc/current/security/entity_provider.html#create-your-user-entity
This latter one even says at 1) Create your User Entity, that a password is a field of User.
I have recently created just that, first I named my classes UserCredentials and UserDitails and because of the confusion of the getUser function i decided to rename UserCredentials to User. I agree with Alex Blex about the relation (manyToOne on the User side). When you decouple your login and metadata you will need to learn how to embed forms or creating your own form models, which is something I am currently working on and you might need to implement callback functions for deleting and updating entities. The more I work on my UserBundle, the more it looks like the FOSUserBundle. There is quite a bit of work of designing it to work well but it's great for learning. If you wish to inspect how the FOSUserBundle works, after you install it, you can find it in the vendor/friendsOfSymfony folder, it might provide a few answers.
I'm working on a project in Laravel for learning the framework.
I create a basic register/login and after that I customize the register part.
What am I planning to achieve is the point where an user can act in multiple roles.
For example:
user1 can be normal user and administrator(with special access to the application) at the same time.
How should I design this from database point of view ?
Personally, I wouldn't create another "user" type entity for companies, but add another table for company data and connect it to a user. That way you are able to keep the default registration and login process.
If you wanted a slightly different form to register companies, I'd add another route & form to gather the "user" information as well as "company" information (company name, phone, fax, etc). Then when the registration is processed you can create the user entity, along with the company relationship with the given information.
However, if you still wanted to create completely different entities with login/registration flows, you'd have to build your own User Providers and implement the contracts needed.
Currently I am using the traditional way to implement member system e.g. A user table and other related table (e.g. user_product) has a foreign key to link to that user
The problem is , how can I work with the member login through facebook?
e.g.
Should I used the retrieve info from facebook to create a new account
for them automatically in my user table?
Should I create a new table e.g. facebook user , then insert in it?
Should I just ignore the login info, without adding it to my database?
The problem I encounter is there is an user_id and people login from facebook will not have it. Therefore, when they use the function e.g. purchase , I can not insert the record. However, if I add them to my user table, there is some info. missing e.g. password, phone..... So what is the common parctise of handling login through facebook? Thanks
There are a few different ways this is handled in practice. Some services require a user to still fill in information, even after the user clicked "Login through Facebook". Unless there is information that you absolutely need, I would advise against this approach.
You could take a polymorphic approach to users and have a regular users table and a Facebook users table. There are other ways to approach inheritance in SQL databases too, but this can get complicated.
A third approach would be to have Facebook id and auth tokens as nullable columns on your users table. This would also require you to either make the password column nullable, or set it to something long and random. This way, Facebook associated accounts function identically to other accounts, with the exception of of the way they sign in. Since you have their email, it should still be possible for Facebook users to make use of a "Reset password" option to get a password.
Edit:
You'll need to create columns for the things you need in order to maintain a Facebook record for a user. Facebook id, oauth token, and oauth secret are among these. When a user clicks sign in with facebook, upon receiving a response from Facebook, you should run a check to see if there is a user with the given facebook id. If one exists, sign the user in. Otherwise, create one.
Even easier would be to look at an OmniAuth solution. OPAuth is one such solution. Introducing something like this may require you to rework some existing code though.
Using Tank Auth for first time along with HMVC. In my application there are 2 type of user one is say student and another is institute.
I created two modules for each user type and separated the tank auth library , both user's registration, login and tables are different from each other.
Now if I try to add any other page which is common to both users like home page, Which library should be used.
I know there must be better solution to handle multiple user problem.
Please let me know where I'm doing wrong. And what should I do to tackle this problem.
You're right, there's a better way to handle this. Duplicating your user / registration system is the wrong way to go.
You'll need to modify TankAuth to include a user type column, and then check for that user type. I'd suggest a new column in the 'users' table for 'user_role':
https://github.com/ilkon/Tank-Auth/blob/master/schema.sql
You could handle the user_type as either an int or enum. I'd lean towards int since enum is harder to change later. You could also add a new table for user_roles but I usually just store these in a config file.
Once the schema is altered, you'll need to add a reference to the new column (along with possible options) in the Tank_Auth code. You'll need to include it in creation, update (data is passed to model from the tank auth controller: controllers/auth.php) and lookup functions. I would add a lookup by user_role as well to the tank_auth model (application / models / tank_auth / users.php):
function get_user_by_role($role)
{
$this->db->where('LOWER(user_role)=', strtolower($role));
$query = $this->db->get($this->table_name);
if ($query->num_rows() == 1) return $query->row();
return NULL;
}
Lastly, you'll want to set the user role to session on login so that you can track the user type (and what content / functionality they have access to).
I've used Tank_Auth myself for several projects.
building on what calvin said, codeigniter does a good job a securing your application, tank auth will verify them, however you need different user levels, this usually falls under permissions. Your job as a developer is to make sure codeigniter does it's security checks via CSRF & XSS( I would suggest you do this in each validaton rule, rather than globally, especially If your admins need to add any tags not allowed suc as "script"). you can see how I personally setup my controllers regardless of my Auth library here...
You need to have a row in your users table called "permissions" which is either a serialized array or json encoded, or you can do a google search on permission bitmasking, which requires an int field
I am trying to create a login system thats generic so that it can be adapted for use in various apps. I decided that 2 main "parts" of the system will be User Meta Data & Roles/Resources/ACL.
1. Metadata
I thought of keeping most data like what meta data are available for users in the database, so that admins can manage them using some GUI.
Problem is how can I then configue how I want inputs to render (textbox, checkbox, radios etc.). Then another problem is validation, filters.
2. ACL
I think for simple ACL it will work fine. But suppose I want say users to be able to modify posts they own. In Zend_ACL that is accomplished with Assertions. I thought that will make a "simple" login system overlly complex? Also it will be hard to build I suppose?
Currently I have my database like
Logging in users: I recommend using a separate controller (call it Auth for instance) that has loginAction and logoutAction. Zend_Auth (Zend_Auth using database) will check the database for the right credentials. Once the user is verified, you will save it in the global accessible place(the Zend_Auth class has methods to do this). This is also a good moment to query which roles the user has and store them.
Metadata part of your application: I'm not sure what the question is exactly but I assume you want to store dynamic information about user and have a GUI for admins to manage this. Why you would render different types of controls? Validating the information can be done by defining a lot of the most common metadata (like Twitter) and create rules for them. In the save action for the metadata you would validate using these rules.
ACL: Resources rarely change, you are better off putting them in a configuration file (for speed). You should give a lot thought to resources: what are they exactly to you? Controllers? Modules? Create a plugin that will preDispatch every request checking the role of the logged in user against the requested resource. E.g.:
$action = $request->getActionName();
$controller = $request->getControllerName();
// role, resource, privilage
if (!$acl->isAllowed($user->role, $controller, $action) {
//go to access denied page!
}
Now that Zend_ACL is used for the global access rules, you are better off checking for specific access inside the action itself (like if ($loggedInUser == $article->author) {//edit the article};).
Also don't forget Zend_ACL can be integrated with Zend_Navigation to hide menu items users are not allowed to use (and more).