I'm working on simple PHP framework which follows MVC best practices. Core classes (config, request, response, router, dispatcher, db etc) are stored in registry which is also some kind of DIC.
The question is - where to put models which also is needed throughout application? For example User model.
One more question regarding this - User model will be created on login. When there is no logged in user, should User model be null or what? I don't like this because is_null() checks will be needed in many places.
MVC design patter is quite straight forward look and the documentation of major frameworks like Codeigniter,Kohana or even kissmvc which is simple and will help u identify the structure of the framework.
And regarding the login question , You can have a separate class to manage the sessions and use this to set if a user model was created not the object it self. You can getter better idea if you read the Zend_Auth Manual. Its simple to understand.
Related
This question already has answers here:
How can I implement an Access Control List in my Web MVC application?
(3 answers)
Closed 6 years ago.
I'm working on an MVC application with this structure:
Request
V
FrontController <-> Router
V
Controller <-> Model
V
View
I have two other components that I need to place in this structure:
Authentification: Logs the user in using the $_SESSION global variable;
RBAC: Role Based Access Control that can check if a role has access granted to a "ressource" (Controller method).
Every users can have any given number of roles (they can also have none).
Now, I need to place those two components in my applications, I need them to be able to:
If the User isn't authed and that the Request requires a authed User to be executed, the client should be redirected to a login page;
If the RBAC sees that the authed User doesn't have a role that has access granted to the required "ressource" to execute the Controller's method, the Controller's method should still be executed but with knowledge that the User did not have the permission to do so (Example: A User writes an article but doesn't have the right to publish it, so the article is saved as a draft and the User is told that a Moderator will have to publish it).
I already have a few ideas where to locate the Authentification and RBAC but I'm not sure:
Authentification could go in the FrontController or the Router;
RBAC could go in the FrontController or the Controller.
I saw someone putting the RBAC in the model but I don't understand why.
I'd like to have some insight on the subject please. Where should I put the Authentification and RBAC components?
Thank you!
In my experience, access control business logic changes as new features are added, so it pays to design flexibility and motility into your access control system. Thus, I would engineer Authentication and RBAC as separate traits, then incorporate those traits into the controller space as necessary.
As described, it sounds like the authentication trait would best be incorporated into your front controller: you know that all dependent controllers require authentication, so incorporate that check early in the life cycle to free up request sockets. If your requirements ever change to need some controllers to be ungated, you can push the trait down into specific controllers or into a base controller class.
As for RBAC, that may apply globally to all controllers as well as locally to some controllers. For example, your FrontController may query the RBAC to build the routing table, while dependent controllers would use the RBAC for their specific needs.
One thing to consider, though: you may also have some RBAC needs in the model. That is, some roles may have limited access to some fields in some models: role A can access all of model X, but role B can only read fields 1, 2, and 3 of model X. (Trust me, I have seen very, very complicated rules around roles that can see and act on what fields.)
Engineering RBAC as a controller trait may make porting to model space difficult. Thus, you may find it better to engineer RBAC as a service delegate and inject it on demand. With a well-provisioned IoC container, a service delegate is just as easy as compile-time traiting.
Finally, I'll add that you're going to want both of these under heavy test (they are important, after all). So whatever you choose, engineer so they can be tested. In my opinion, both traits and delegates are easy to test in isolation and either would be a good choice for implementing the necessary logic.
In a typical MVC application the authentication check (i.e. "if not auth, then stop and render the login page instead") is done very early in processing the request, while the business logic (i.e. "if user has this permission then this happens, otherwise that happens") is handled within the "C" (the controller).
Most frameworks have a mechanism in place for tests like the authentication check your are describing - names vary but I have often seen it called "middleware".
The role based access control is purely your implementation.
I am creating an application with the help of codeigniter. People can register and log in to the application. User can view each others profile as well.
I noticed that I am using the functions like getting a username from user id, email from user id...... quite a lot. The common thing I noticed about all these functions is that they all are supplied with a user id as its parameter. All these functions are in the controller.
I was thinking to put all these functions in a helper file. As it is quite easy to call the function from helper file. Since, I am using these functions quite a lot, I can directly use them in views if they are from helper file.
Now my question is, is it safe to put these functions in helper instead of controller from the security point of view ? As these functions directly access the database to get the crucial information from the users table.
I know this question might be regarded as very much to a opinion based. But at the same time, I am trying to get the exact answer whether it is safe or not.
From a "secure" standpoint, they're both in your code and not visible by the end user. From a testing standpoint though, code that accesses your database is best tested when it's isolated from code touching other components like UI (which is generally in the controller). This sort of thing would normally go into the model or model helpers in an MVC pattern.
Cake's documentation says "Most commonly, controllers are used to manage the logic for a single model." I'm finding this is uncommon for most of my code, and I don't want to break convention unless it is proper to do so.
For example, my application sends a user to their account dashboard after they log in - this uses data from probably half a dozen tables, not all of which are even related. Do I create a "dashboard" controller for this (even though there is no dashboard model or table)? Or do I create a dashboard method in an existing controller?
Thanks, Brian
I have a similar situation and how I handle it is keeping the actions that connect a lot of models in the controller that is the most centric. For instance, my user can create voicenotes, comments, has settings, has twitter and facebook information. All this information I can get from my user model $this->User->Voicenotes->find('all'), for example.
I believe creating additional controllers might just confuse you, use what cake gives you, you can specify that models are to be used in a controller either by setting the $uses variable or using loadModel in the controller action, if you have your relations set up you can just do it the way i described before, no need to create additional controllers.
I guess it depends on how you want your own app to work and what comes easier in your situation.
the situation is this.
my client (who also is a programmer) asks me to develop an address book (with mysql database) with a lot of functions. then he can interact with some class methods i provide for him. kinda like an API.
the situation is that the address book application is getting bigger and bigger, and i feel like its way better to use CodeIgniter to code it with MVC.
i wonder if i can use codeigniter, then in some way give him the access to controller methods.
eg. in a controller there are some functions u can call with the web browser.
public function create_contact($information) {..}
public function delete_contact($id) {..}
public function get_contact($id) {..}
however, these are just callable from web browser. how can i let my client have access to these functions like an API?
then in his own application he can use:
$result = $address_book->create_contact($information);
if($result) {
echo "Success";
}
$contact = $address_book->get_contact($id);
in this way, my controller methods are handling the in and out with the Models. there will be no views, cause i just have to return the data/result from the Models. and he can just use my "API" functions.
is this possible?
cause i just know how to access the controller methods with the webbrowser. and i guess its not an option for him to use header(location) to access them.
all suggestions to make this possible are welcomed! even other approaches to let me use CI to develop. perhaps there already are best practices regarding this kind of cross framework collaboration?
thanks
MVC seems to have dispersed in its definition. This definition I will offer should be ideal for you.
Models are where you build your business end of the application. Operations such as create_contact, delete_contact, and get_contact belong in the model layer. The model layer is what builds your application API and should be entirely independent.
Consider the controllers purely as the user's puppeteers. Controllers accept user input - the validation, sanitation, and whatnot may be done elsewhere - and invokes the API you've already setup in the model layer. Also, controllers then specify what view to use - however complicated or simple your presentation layer is.
The presentation layer usually isn't the difficulty. As long as you are only using read operations in the view you should be fine.
To clarify, if a user wants to create a new contact, the controller may need a method called create_contact that accepts the appropriate input. However, the actual operation of creating the contact must be done in the model layer. This will allow your other developer to reuse that same operation in a completely different application by loading your model, which was already designed as an independent entity.
Sorry if this is a badly formed question, but I'm trying to make my web applications (using PHP) more OO. *EDIT* I'm developing the Framework myself */EDIT* Everything is great so far, I've made a Front Controller system that taps into a MVC system. The FC figures out what page you want, loads the specific page Controller (*EDIT* which extends an abstract Controller Object */EDIT*), which gets anything it needs from Models, and then calls the appropriate View. Very basic.
But now, I need to make an admin section (quasi-CMS). How does a login system fit into the grand scheme of things? Do you set controllers as needing a login? If so, how? What If you only want certain views of a controller requiring login?
Thanks in advance.
Which framework are you using? I would advise using a framework such as Zend or CodeIgniter instead of rolling your own.
Anyway, the reason I ask is because these frameworks do usually have login frameworks available for them.
How it generally works is, each controller subclasses an abstract controller class. In your controller constructor, what you do is set a flag to say that it requires a valid login. Then the abstract class will check for a valid login on each request and can take appropriate action (i.e. redirect to a login controller).
Obviously you can make it more fine-grained / complicated than this, i.e. on a method-by-method basis.