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.
Related
I'm fairly new to php oop and I'm starting to get the hang of things. Though I have extended procedural experience, I've only recently started to build my own MVC framework, mainly for learning purposes. I got to the stage where I know how to route url's to controllers and models and render views based on what's requested. What I struggle with is a conceptual thing:
My application has users, which have to log in in order to use it. If you're not logged in, nothing happens. These users are objects and have methods like login(), logout(), auth() etc.
At the same time, I would like to have a "module" in my application where certain users can manage users, like root for example. A page where I can see all users, add new ones, remove existing ones, reset passwords etc. ...
While I know how to build the latter, I'm confused about where the login() and logout() actions should go. Are these part of the UsersController or should I have a separate class for them, despite technically dealing with the same object type?
Thank you!
MVC and the chess game
This is to help you understand what's the Model, the View and the Controller and how each layer might be used.
Let's suppose that you want to implement a chess game in MVC.
The rules are essential for a chess game. The rules are the Model layer.
You may play with with a wooden board, or using a computer, or using only your mind to represent the state of the game. The representation of the game is the View layer.
Of course, the rules and the representation of the game don't tell how the moves are chosen. There might be humans or some machine playing the game. Different humans and machines usually make different decisions. Those are the controllers. The fingers, pointer devices, keyboards are also controllers. They interact with the Model. All those controllers belong the Controller layer.
Let's suppose that in the Model layer there's a method:
MoveResponse ChessGame::move(from, to)
That doesn't mean that there shouldn't be some method:
void HumanPlayer::move(from, to)
The human interacts with the game using, for instance, a mouse. There could be something like that:
MouseGameController::onClick(x, y)
Using the board representation (from the View), it would convert the click position to the board position (in the model), check if there's some game piece there and notify the View for visual feedback.
If there was some game piece and the player clicks again, void HumanPlayer::move(from, to) would be called, that would call MoveResponse ChessGame::move(from, to) and the returned MoveResponse would be used to update the View. Some method would evaluate the content of the MoveResponse and call the appropriate method, for instance, to move a piece with an animation and make some sound.
Where to put the login and logout
Someone has to login and logout. That's a decision made by the user, therefore it should be in the controller.
Nevertheless, since it's possible to login and logout, there are users models. You need to access users data, change them, know what's the current user, etc. I believe the login/logout functionality should be implemented in the Model, but how that's invoked should be implemented in the Controller.
In the Model it's not important how you proceeded to login or logout, or how those events were triggered: you clicked the "Esc" key, or you clicked a button, or you sent a HTTP message, etc. That's the Controller responsibility. Implement the login and logout without thinking how the user will login or logout, then use something else to call what you implemented when the user wants to login or logout.
Usually, the idea controllers are limited to map the actions of a router to a function, but the db connection and other things involved exported to other layers of your framework and just to be called there.
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.
Imagine that I want to login a user. The user sends the validation data, and my controller gets the POST request so it calls a User Repository method in order to registered him.
I'd like to start the user Session with the user data. But how should I start the session? Should it start in the controller or the model? I think it should be the model, since it's my business logic who says that session have to be started. But how? Should I pass the session object to my Repository?
Im using Doctrine for the model layer, and my own framework for the rest. I use dependency injection but I don't see how to get access to the Session from the entities / repositories layer.
The only solution I've got right now is to call the repository method passing the session as a parameter, but it doesn't feel right.
I think session handling should be done in the controller, but just personal opinion. If you are trying to have a clean separation of concern, it should defiantly be done it the controller. It doesn't make a lot of sense to make Doctrine (which has a very strong focus on abstraction and independence) dependable on the session.
Make a controller which calls a method from model to register the user. The model method returns the user specific data, which you pass to the Session (from controller). You will probably use session in a lot of places, not relevant to model. Why make it stretch to two levels, if you can encapsulate it in one?
I am facing some confusion because i have decided to convert from procedural to oop, I Find it more efficient.
So anyway I've got some questions i hope i find answers here :)
Let's say am working on a php Registeration System which requires
1-Signup process
2-Activation Process
3-Login process (which requires)
Validating inputs
Validating Sessions, etc
The questions is: Should i make class for every process Or i can combine all of them into one class named 'User', with methods to login, signup, activate and so on, Or can i make 1 class named USER which has user's properties, and signup, login classes extends it ?
Should i use separated classes for Sessions, Validating etc ? or just normal Checking inside the main class
Should i Separate ADMIN classes from normal classes ? meaning I have a USER class, which has methods, to login user, signup user etc, should i add more functions for admin like DELETE user, UPDATE user ? or separate it from the normal classes
You should make a User class with different functions for login signup and whatever.
You should separate different functions into as many classes/objects as you feel suits. For instance, with your User class you might have a Session class which you use within your User class to do the session management stuff. You could also create a Person class which User inherits from. This can have functions like printFullName and such, whereas the User class has auth specific stuff like login and register.
Again, its up to you. You can do whatever you want. I would probably have a UserAdmin class which has functions like deleteUser($userid) and editUser($userid) just because then its not confusing it with the auth side of things. However it can be done the other way. You could call a User object for a specific user and call deleteUser() on that to delete the user. Its what you feel most comfortable with.
As with all my answers, its what you want to do. There is no standard to this, and no rules. OOP is mainly about layering everything so that it makes sense, structurally, and about creating reusable code.
Another thing you want to look at is MVC programming. MVC stands for Model, View, Controller. In this set up you actually differentiate objects not by category (e.g. user, page etc) but by their function (e.g. model - connects to a database, view - has the code to layout a page, controller - computes stuff and passes data to the view). If you look at something like codeigniter then this will become more apparent to you.
Now you can create a model for users. In this model you can do all the database stuff, adding, editing, deleting users and such. This can then interface with a controller which will layout the page, e.g. seeing if the user is currently logged in, calling the user's model and getting the name of the user from the model, then passing it to the view to display on screen. This will make much more sense when you start using frameworks like code igniter.
Anyway, good luck in your learning.
It's really your own choice what is in a class and what is not. Mostly it's about what you find to create a good overview and what makes certain use-cases easier. In this case it will most likely cause more confusion if you split these operations, instead of putting them under the same banner.
I'd under most circumstances choose to put validation, signup, etc. in the same class. If admins are also users (and not a whole new table of users for example) I'd also include these in the same class - Or maybe create an admin class that extends the user class.
But there's no ultimate law of what is put in one class and what is not. It's about trial and error and seeing what gives you a good overview, and when you come to building abstraction layers, extending classes, etc. you need to be a little more careful. Taking the right steps can save you a ton of work in later work with extending classes.
I made the switch about 6 months ago from functional to OOP. I read a shitload of papers trying to figure out what the big deal about OOP is.
I think a conceptual understanding is important in this case. Think of an object as a physical thing.
A car:
A car has properties:
color
remaining petrol
top speed
A car has methods:
start
stop
accelerate.
1) A user is an object, login, logout, signup are actions/methods that a user does.
2) A user has session variables(properties) so I would place them as properties in the class
3) An admin user has more methods, but still needs acess to old ones. So idealy an admin user should inherit the properties and methods, I think this is done with the Extends keyword. This is called subclassing, or inhertance.
You best is to google "understanding oop concepts" and read whatever connects with you
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.