We are developing an application in Laravel 5 where users can login and based on the licenses assigned to the user, multiple "content types" are available within the app. The business logic and presentation logic differs based on the selected content type. The user can select the content type to work with, or, if only one license is available, will be directed to the homepage of that content type.
Now I am trying to figure out how to handle the selected content type. Storing this in a session is imo not the way to go because a user must be able to use multiple content types in one browser session simultaneously.
I figured I need to start with grouping all relevant routes and prefixes them with {contentType}. Also, add a Middleware (named something like SelectContentTypeMiddleware) and let that middleware check if the content type exists, and if the logged in user is allowed to have access to it.
Furthermore, every descending route (in the {contentType} prefix route group) also must handle the route parameter $contentType.
I am trying to figure out of this is the right approach. I was looking at this blogpost which addresses the case for setting the app locale. Using app()->setLocale($locale) the locale for that request is set. I was wondering if a similar approach for my case makes sense, or that including the route parameter $contentType in every route is more advisable.
Related
I have a (hopefully) quick question regarding sessions. Whilst I have used sessions extensively, I have not used them in a situation whereby the values change depending on a users actions.
After logging in to my application, a user can select a company area, which has many levels of pages and folders. All of these pages will need this 'company_id'. At the moment I send the company_id via GET, but as I get deeper into the application this is becoming increasingly hard to maintain, with various other data being stored in the URL.
Therefore, when a user selects their company, I could set their company_id in $_SESSION array. However, when a user changes company, I would then need to change $_SESSION['company_id'] to the new value.
Is this a good use of sessions? I could potentially clean up my urls by using session data rather than always using GET, but I am unsure if this is a recommended way of using sessions.
Thanks in advance
This is a bad implementation of the HTTP design philosophy. All HTTP requests should be self contained, RESTful. All information needed to get a specific page should be present in the request itself (URL, headers and body), not dependent on hidden state.
Super trivial example: you can't copy a URL to someplace or someone else and have them see the same page. The content of the page is dependent on session state, which has been laboriously set through the visit history of several previous pages. To return to this same page, you need to retrace the same steps, recreating some hidden server-side state to arrive at the same page.
This gets even more complex and messier if you take into account that a visitor may want to open pages requiring different states in two or more simultaneous tabs/windows.
All this isn't to say that it can't work, only that it's hideously complex and will break the usual expected behaviour of browsers, unless you really bend over backwards to somehow prevent that.
If the many levels of pages and levels are per-company, you can put the company_id in a specific include file - this part of the site being dedicated to a given company.
However if they're shared by multiple companies, and this is probably what you want, this is potentially misleading, or even dangerous depending on the user actions, since the user may jump to a given page (link...) and access a page with unexpected data linked to a company which ID is provided by the session or cookie.
You could dynamically build the links on a page, based on IDs, to ensure consistency during the navigation from that page. Any direct "jump" to another part of the site will not carry the ID with it (and the page may offer to select a company).
Depending on your web server and if you have control over it you could build the URL having "company ID" as an element of the URL path, not the GET parameters
Eg
http://example.com/invoicing/company382/listprices.php
using a rewrite (web server configuration) to change the URL to be actually used to
http://example.com/invoicing/listprices.php?compid=company382
(URL not visible to the user) that informs of the company ID via the GET parameters.
I have a website that serves up various information for users who have accounts on it by accessing information listed under a username and a category. Using the variable names, u and c, the url looks like this:
www.originalwebsite.com/user.php?u=username&c=43
I want a user-defined custom domain to remove any evidence of a username variable or variable name. Other variables (like category) are fine to remain. Ideally, this would result in the following link pointing to the one included before:
www.customdomain.com/c=43
My reasons being that the custom domain would be unique for the user and, therefore, would be remove the need to specify the user (in theory, not in practice so far) as well as presenting the site from a custom domain in a manner that looks like a single site, rather than the portal like options of the original.
I can get www.customdomain.com/u=username&c=43 to work but am trying to think of the best method to remove reference to the username when using the custom domain (both the variable identifier and the variable itself). I'm struggling to think of how I'll inform the original website of what user account to use if it's not mentioned in the url itself.
At the moment my best idea is to let user.php handle this with a condition of whether the request is from originalwebsite.com or a custom domain. If finds that it's the latter, it checks it against a database listing and finds the relevant user settings discreetly. This feels like quite a slow procedure, however.
If my example is not clear, think of sites like Tumblr, where you can add a custom domain and, from that point on, urls make no reference of your user name.
From some discussion here and further research, it seems as though there's no quickfire way of doing this. It looks like I'm stuck with either keeping some form of reference that can identify a username in the url, using a cookie or sticking with my original idea of referencing the custom domain against a database to find the appropriate user and settings.
I've gone with the database referencing option as I need to remove references to any username from the url and I can't always rely on cookies. I need a 100% success rate of correct redirection.
I've changed my user.php file to check if the request has come from originaldomain.com or newdomain.com. If it's from originaldomain.com, it looks for a username variable in the url as it should have one for any user that doesn't have a custom domain. If it comes from a different domain, it checks to see if this domain is listed in the database and finds the user from this. There's a few catches that I'll need to trial but I've got 90% of the issue solved.
I am developing a dynamic website using PHP. When a user of the website creates an account, a profile page should be created for that user. Say, a user called 'dev23' creates an account on my website, his profile should be accessible through the link www.mysite.com/dev23
How do I create such a thing? Should I create a standard page like userprofile.php which is populated with data specific to the username provided? Or should I create a permanent webpage for every user?
Please let me know the right approach to this porblem.
Is the www.mysite.com/dev23 meant to be public or only visible to the logged in user?
If it is only visible to the logged in user, you can create a myprofile.php file which retrieves the logged in user from the session and retrieves data accordingly.
If it is meant to be a URL that other users can hit, you probably want some sort of userprofile.php page with data passed along to identify the user to be viewed. For example, the url might be www.mysite.com/userprofile.php?user=dev23. If you are using Apache for your web server, you can look at using mod_rewrite to make the URL prettier. Thus, you could have the URL www.mysite.com/user/dev23 routed to userprofile.php?user=dev23 and your PHP processes the same. It is just a means of making URLs be more user friendly than a naked query string. This is common amongst many PHP-based CMS systems such as WordPress, Joomla, etc.
Ideally you should be creating a single file that handles all users.
Certain frameworks like SkyPHP allow this by defining the attributes after a valid page as "queryfolders" which can be used much like GET/POST variables.
If you are not using a framework, I might suggest you look into using one to simplify your tasks.
SkyPHP also has a functionality where a single field in a table can be used to pull this data simply by defining the page as _table.field_name_
It will check to see if there is a matching table and field to pull the data from and will automatically pull the id of the record whose field's value matches that of the url and assign it to a variable.
Example... If we have a table called category and a field named slug, one would create a page named _category.slug_.php
Then the url... http://mydomain.com/watches would look for "watches" in category.slug and pull back the identifier of the record as $category_id with $category_slug available also.
It would solve your issue if you are willing to give it a shot.
Again refer to the documentation here... http://switchbreak.com/skyphp
I am developing an application in php codeigniter. Now I am worrried abt the permission.
I need page wise permission, page may be add records page, edit page, delete page and print report etc. There will be many users as well, and applicaiton will grow with passage of time.
If I implement ACL that will better for me or not
what can be ideal for me any suggestion.
First, let's clear up some terms: I personally use the security term for things like preventing SQL injection, XSS attacks, where we have to validate input, filter/sanitize values, take care of the dynamically generated SQL commands, take care of properly escaping output (for JSON or HTML text or HTML attributes), etc. This is not about what you are asking, if I understood well.
The access control or permissions system is where you give or deny access to a function for a user. It can be secure or not. I understand that to deny a user which does not have permission the access to a function may sound like "security", but I wouldn't use this specific word in this context, to avoid confusion.
Now, the answer:
I strongly recommend you create a few base controller classes to your needs. Read the following blog post carefully (it is short and useful): http://philsturgeon.co.uk/blog/2010/02/CodeIgniter-base-Classes-Keeping-it-DRY
A code to check if the user is properly authenticated (logged in) is essential. If the user is not logged in, redirect to home page or login page.
For fine-grained control, you could create your ACL in the database using the users table, plus an actions table, plus an acl table...
The users table would contain the users data (id, name, login, password, etc)
The actions table would contain the id field and at least one more field containing what suits best for your application: it can be only the controller class name (the first part of the URL, for example: "products"), granting access to the whole "products" controller or not. Or you may want to include both the controller class AND the method name (the first and second parts of the URL, for example: "products/add" and "products/delete"), and so on.
To decide about the actions table is the most decisive step. Think very well about it, balance your needs (your "true" needs)... I developed a system where each and every action has its entry. It is good, but it needs work to be maintained.
A very useful column for the actions table is a human-readable description of the action.
The acl then would be nothing more than a column for the user id and another column for the action id.
A "master" grant/deny access field in the users table is useful too, in case you want to temporarily deny access from a specific user, without having to delete all his permissions and maybe having to restore it later.
With the database tables and your "controller/method" or "actions" strategy well defined, you can easily code in your base controller class a function which checks if the user have permission to execute the requested action.
This is the basic. In my system, I have the users administration interface, where I can grant/deny the actions for each user (I use an ExtJS tree with checkboxes). One of these actions is the own user management. I have gone one step further, where the user who can access the user management may "delegate" (grant/deny) to other users only the actions he himself has access to.
The system has several modules, and functions. The interface does not show anything the user does not have access. So, I have users who can see only a single or a couple of modules, and they don't even imagine the existence of the other modules.
It requires more work to manage all this, but the result worths.
I also log each granted access, so it is possible to track who did what, and when. This log feature is very very easy to add, since you have this base controller "master function" allowing or disallowing the users to perform the actions.
I hope I have helped. I've just shared a bit of what worked (and works) for me...
Is there any way I can make user URLs? something like
www.domain.com/username
I know I probably have to use a route system, and I do use this a lot for other URL requests. But the thing is, I need the username to dynamically create the user profile, if it exists. But do I also need to keep my other controller classes in mind?
Thanks!
I see you realize the potential for a user to step all over your other valid routes by creating a matching user name.
You could try routing all requests as usernames, but providing a trigger for your other controllers (and other valid routes):
// Route everything to users profile
$route['(:any)'] = 'users/profile/$1';
// Route all requests after "my_trigger" as normal
$route['my_trigger/(:any)'] = '$1';
* I'm not sure, but you may need to append more /(:any)s to the trigger routes.
This would mean that my_trigger would have to be an invalid username, but would be the only invalid user name.
The idea is that all non-username requests must be preceded with the additional "trigger" segment, otherwise it will be considered a user name. So /blog now must be accessed with /trigger/blog.
You could of course do the same with the user name instead, but end up with a less pretty url, like /u/username, or use a query string like ?u=username.
Another option is to specifically whitelist segments that should invoke a controller as normal, and blacklist them from the available user names, while routing all other requests through your users controller.
In any case, if the user name doesn't actually exist - you need to respond appropriately, so there is no real need for "dynamic" routes (i.e. creating a route for each and every user).