We want to add 4 types(or groups) of users to our website, they should access only associated pages what we allow while creating those groups. So should we set an array of permission and check at top of page if user has permission to view this page or any other way like creating db tables or writing class. Please help.
Normally I'm not a big fan of using Zend outside of a fully Zend application, except with Zend_Lucene, but I would recommend using Zend_Acl in your application, which handles this task transparently to your application. It's quite easy to use, here you have a sample code from the Zend dev:
$acl = new Zend_Acl();
$acl->addRole(new Zend_Acl_Role('guest'))
->addRole(new Zend_Acl_Role('member'))
->addRole(new Zend_Acl_Role('admin'));
$parents = array('guest', 'member', 'admin');
$acl->addRole(new Zend_Acl_Role('someUser'), $parents);
$acl->add(new Zend_Acl_Resource('someResource'));
$acl->deny('guest', 'someResource');
$acl->allow('member', 'someResource');
echo $acl->isAllowed('someUser', 'someResource') ? 'allowed' : 'denied';
Hope I can help,
David
I created 2 tables:
1) Users (ID, Name, Password, GroupID)
2) UserGroups (ID, Name)
Then build a function which checks if the user is in a group. On the top of the page you check this and show the page (or not).
If you want to extend this you can create a table actions and a crosstable, which links an action (access a page or edit something) to a set of usergroups. This way you can have multiple groups on one action. These are those tables:
3) Actions (ID, Name)
4) Group_actions (GroupID, ActionID)
What I have to solve this issue is this:
I have created one table with user levels.
Every time the user logs in, I retrieve this level from the database and save it in session variables.
In every page, I check if the value of the session variable that correspond to the user is allowed to see this page.
EDIT: tO check, I used this function:
function checkPermission($allowedLevel)
{
if(isset($_SESSION['level']) AND ($_SESSION['level'] == "$allowedLevel")){
return TRUE;
}
else{
return FALSE;
}
}
And in the top of every script I have:
if(checkPermission($someLevel)){
// Run the script
}
else{
// Manage unauthorized access...
}
EDIT 2: My tables are like this:
I have a table for levels: user_type(id_level, level) and in the table where I store the user information I have a foreign key to the id_level for each user.
Every time they log in, I get the user information by making a join between the table user and user_type (Since id_level is a foreign key in my user table)
Related
I have to create an application in which there are 5 types of accounts
Super admin
Inventory admin
Shop owner
Shop manager
User
So How can I create these multiple accounts with Laravel, should I use different middleware group for each. also, i have to create privileges with all.
Currently, I am using it with different middleware and session for each and separate tables in DB for each, but I don't think so that's a good way to do it.
What is the way to create these multiple accounts with Laravel.
#Thanks
In addition to providing authentication services, Laravel also provides a simple way to authorize user actions against a given resource. Laravel's approach to authorization is simple, and there are two primary ways of authorizing actions: gates and policies. Please refer the Laravel documentation for more details.
Authorization in Laravel 5.5
As #Fawzan has said, if you only working with Roles (or a Group) then just create a groups table and then link each user to the appropriate group. You then have a single user table with a groupID for each user.
Then you could create a blade directive to help you in your app to check if a user has a specific role. (Place this inside your AppServiceProvider)
Blade::directive('hasRole', function ($role) {
return auth()->user()->role->name = $role;
});
// Or a little more performant if you call the directive many times.
$roles = Role::all()->pluck('id', 'name')->toArray();
Blade::directive('hasRole', function ($role) use ($roles) {
return auth()->user()->roleID == $roles[$role];
});
You can add a column to users table called user_type and
insert the decimal value for each user for example
Super admin = 1;
Inventory admin = 2;
Shop owner = 3;
Shop manager = 4;
User = 5;
and based on the user_type you can do all your operation.
I have four different types of users login in to my website like admin, superadmin, company, and employees. Each of them have different set of pages to see but some common pages as well. Now I am having four different tables to manage them with same login screen for admin and superadmin. When either admin or superadmin logs in I will go and check two tables one by one before giving access. I have a separate login screens for company and employees. Is this the accepted way of doing it?
Actually, I want this to be changed to a single table with all users in it and a role table to differentiate the roles. I believe a four-table concept is really bad. I can't simply make it to one table because the previous developer had a habit of saving user comments and user activities in text files which is used on website.
Am I right in the way I think that a four-table login system is bad? Is storing logs in a text file that are directly used in website a good idea or not?
You have 4 tables? Just use one user table and a field that can either be 'admin', 'superadmin', 'company' or 'employees'. Then you can have unlimited types of accounts. (I would do number codes like 1,2,3 or 4 instead of string codes or ENUM type field).
But yeah, your single table idea is fine. If you want a role table, do a foreign key to your role field and link it to your role table. You can have a single login too instead of different ones for different users and check for privileges based off that foreign key value.
Here's my suggestion,
Instead of using four tables for your users, it would be better to use one.
You can create you basic user table like this (change rank to what suits your site/script):
ID username password email bla bla bla rank
So instead of using four tables, you can make your PHP script check if the user has the desired access level.
Here's a simple function to protect pages from lower access level users:
function required_level($level){
$user_level = mysql_return(mysql_query("SELECT $rank FROM `Accounts` WHERE `user_id` = $user_id"));
if($user_level<$level){
header("Location:index.php");
}
}
Then on each page you want to protect from lower level users accessing it. You can just call required_level(4); and the page will only allow users with this level or over to access the page.
Example:
Bob is a employee so he has a user rank of 1,
Joe is a superadmin so he has a user rank of 4
Both users login normally, and both try to access admin.php.
admin.php starts with required_level(4); so Bob would be redirected to the home page (you can also pass an error) but, Joe would be bale to access this page because his rank is the same or above what is required to access this page.
So, here's my super long explanation on what you can do! I hope this helps and gives you some ideas on how to make your user tables better and easier to create protect pages :)
First of all, you can do the whole thing with a single table. In that table you should have fields like username, password, typeofuser and other necessary information.
Retrieve user information like:
$username = $_POST['username']; //Retrieving a username from HTML login form
$row = mysql_query(sprintf("SELECT * FROM table WHERE username ='%s'", mysql_real_escape_string($username))); //Retrieving a row from the database
$res = mysql_fetch_array($row);
$type = $row['typeofuser']; //Retrieving whether it is administrator, super administrator, user, etc.
if ($type == "admin")
header(Loction:adminpge);
Similarly, you can check any type of user and can redirect to another page.
I am new to php and I an currently creating a e-commerce site. I have created a CMS backend for the admin to add/edit/delete products, manage orders, manage shop configuration and add/edit/delete users.
I am having trouble finding out how to set user permissions/access rights so that:
- General staff only have access to managing orders and
- management staff have access to everything
So basically giving users a role which will give them restrictions or full access to everything.
Is there any tutorials or anyone with previous experience of adding this feature who can point me in the right direction?
Any help will be greatly appreciated. Thanks
An alternative design to what #Johnathan suggests would be a user HAS_MANY roles and each role HAS_MANY permissions.
Users:
+ id
+ name
Roles:
+ id
+ name
Permissions:
+ id
+ name
Then you link users to each of their roles, (and roles to each of their permissions), like this:
RolesUsers:
+ id
+ role_id /* Associate a Role to a User */
+ user_id /* Associate a User to a Role */
RolePermissions:
+ id
+ role_id /* Associate a Role to a Permission */
+ permission_id /* Associate a Permission to a Role */
Rather than cascading roles, or only allowing a user to be in a single role - users having multiple roles provides the most amount of flexibility.
Permissions are associated with Roles, and Users are associated with Roles. While there are, undoubtedly, many ways to implement this type of system, what follows is a quick concept from which you could begin thinking:
Users:
+ userid
+ roleid /* Associate a Role to a User */
Roles:
+ roleid
+ rolename
Permissions:
+ permissionid
+ permissionname
RolePermissions:
+ roleid
+ permissionid /* Associate a Permission to a Role */
Note in the first table how the role is associated directly from within the user table. You could break this out and put it in its own table if you wanted to assign multiple roles to a user.
Once this is all in place, or something similar to it, you can track the user's role via a session variable, and determine whether or not the user is permitted to perform any given action by looking up the id/name of that action, and the id/name of their role, in the RolePermissions table.
if ( $user->allowed( 'deleteUser' ) ) {
$users->remove( $uid );
}
Of course the database side is only the first part of the work. Next you would need to implement the connections between the database, and your code.
There are several ways of doing this that depends on how your app is going to grow. If you're pretty sure you'll only have these two profiles, then just add a "profile" field in your "user" table.
I suppose you have already implemented the login management, then you probably keep the logged user id in session. Just keep the profile type also and every time you display some component that should be accessible to the managers only, wrap it in
<?php if ($_SESSION['logged_user_profile'] == 'manager'): ?>
<!-- display your thing here -->
<?php endif; ?>
Note that this would only hide the elements. You would have to perform this check everywhere in your code also to prevent the corresponding actions from being executed...
A (much) better way if you use an MVC framework like CodeIgniter for instance would be to hook all requests through your access controller and redirect the user to a "access forbidden" page if he tries to access something he's not allowed to. This way, your access is controlled in one spot only.
Well, this is a complex subject that heavily depends on the architecture of your project so sorry if this doesn't answer your question correctly.
Extending from Jonathan's structure, I made a few modifications :
Users:
+ userid
+ roleid /* Associate a Role to a User */
Roles:
+ roleid
+ rolename
+ roleinherit /* Added this field */
Permissions:
+ permissionid
+ permissionname
RolePermissions:
+ roleid
+ permissionid /* Associate a Permission to a Role */
Being able to inherit from other roles can really help simplifying access control. For example, you could say that the "moderator" role inherits the "user" role which inherits the "guest" role. That way, you never have a guest that can do things even a moderator can't do.
Of course, this structure might be harder to implement as you can no longer create a simple query to check. A good way to handle these would be to create a recursive function that pulls data for the user's role, then merges it with the results of this function for the inherited role.
function getPermissions($roleID) {
// get info about this role and store it in $permissions. Assume we also set $inheritFrom
if ($inheritFrom == 0) return $permissions;
else return array_merge($permissions, getPermissions($inheritFrom));
}
Make sure to cache the results of this function, because it might become heavy.
I am thinking about a schema design that involves having users and user roles, but I am not sure what would be the better route.
Option 1
Create three tables, one with the user information, one with the role information, and one with th user role relation.
users {
u_id,
etc
}
roles {
r_id,
r_name,
etc
}
user_roles {
u_idm
r_id
}
Option 2
Create two tables, one with the user information, and the other with role, role info,and relation info.
users {
u_id,
etc
}
roles {
r_id,
u_id,
r_name,
etc
}
Option 1 is more robust but requires an extra join. Option 2 will require an extra primary key but will only be one join. If I ever change the role name, it would take longer to update with option, but I don't forsee updates being frequent.
For a scalable solution, which would be better? What other insights in my missing? This is for a mysql and postgresql solution.
Option 1.
What good is a role if only one user can have each role?
If you have 100 registered users there would be 100 duplicate definitions for "registered user".
The more "etc" there is the bigger your db will get.
Having that many duplicates will slow down your database and in the end things will be a lot slower even if you have one join less.
If you run lots of role based querys and relly eel like you need a database like the one from option two you can still create a view and have the database cache it, but I doubt that this will do you any good.
I would go with the first option with some changes:
- each user can belong to ONLY ONE group
- create a table defining privileges
- each group has a list of privileges
The privileges defined could be mapped to various modules of the application or to specific functionality.
The solution is simple, flexible and fast.
Both privileges and groups tables should be pretty small, so extra JOINs won't have such a critical impact. Also, the authenticated user privileges could be stored in session and not loaded everytime.
There will be more benefits in long term, since the solution is very flexible and easy to extend.
For example, you will create a new module called "Configuration" and you want to create a new user group called "superadmin" to have access everywhere and "configuration". You would simply make changes in the database: create group 'superadmin', add privilege 'configuration', set all privileges and that's it.
My web app is going to have two types of users that are 100% different - in fields, functions, and purpose on the site. The purpose of one type of user is to post blogs, and the purpose of the other is to read them and "follow" the posters.
The ONLY stuff they have in common are the need for an id, email, password and a couple other bits of meta data such as date joined, etc.
Should I attempt to stem them from the same account table, or make one table for each?
NOTES
-One potential thing to think about is that, to prevent user confusion, I think emails between the two types of accounts should be unique.
-Readers and Authors will have different sets of data that will need to be stored about them aside from the normal "account" meta data.
I would separate them.
TABLE User {
id
email
password
salt
created
modified
}
TABLE follower {
user_id
...
}
TABLE author {
user_id
...
}
Over time your application will grow. Perhaps now you have two destinct roles - but it may change in the future. You may have authors that also follow other authors, or followers that are "upgraded" to authors. You might also start adding other "roles" and want something like this:
TABLE user_role {
user_id
role_id
}
TABLE role {
id
name
}
Define "user". If a user is somebody who has registered him or herself on your site, using an e-mail address, password and nickname, and who can log on, then stick everyone in the users table.
The things users can or can not do on a site does not differ for a user. It's their permissions that are different. Map permissions to users in a separate table. Don't create a table for each type of user.
Otherwise, when you're adding a new kind of permission in the future, you don't have to add a new table for that type of user (and alter all (sql) code that handles with users: logging in, resetting passwords, and so on). You just add a new type of permission, and map that to their respective users.
it will save you allot of work to just have one table and have a single column in the table that defines which type they are .
No, make one table for each. It will be easier to manage, it'll be scalable