Would it be advisable, if i am doing authentication in a middleware and adding some data to the \Illuminate\Http\Request $request object and using that data in the controller by injecting \Illuminate\Http\Request $request into the controller method?
The reason, the app needs to make a database call to find out if the credentials are valid and if it is, it returns something like a primary key that i use in subsequent db operations.
At the moment, everything is done in the controller. If i were to use a separate middleware for authentication, can i bind the data that my controller needs to the request object if the middleware check passes? if so, how should i go about doing it?
Inspiration - Expressjs way of binding and passing data along the request through a stack of middlewares / routes.
I dont understand - why dont you just use the Laravel authenticator?
You say:
The reason, the app needs to make a database call to find out if the credentials are valid and if it is, it returns something like a primary key that i use in subsequent db operations.
And that is exactly what the Laravel Authenticator does?
Then in your controller you can just do
`auth()->user()` // gives you the user record
`auth()->id()` // user_id from the DB
`auth()->user()->name` // gives you the `name` column off the record. You can change it to anything.
Edit: Meanwhile - you can still use the Laravel Authenticator package whilst using a legacy system for authentication. In your middleware you can do something like this:
if (doLegacyCheckHere()) {
Auth::loginUsingId(1);
}
This means you can do your check via the neo4j graph db - and if it returns true that the user is authenticated correctly - then you just log them into the Laravel system yourself.
Yes, that is probably a good way to do it, as the build-in Laravel Authentication system works the same way: you can access a logged in user via $request::user(). See http://laravel.com/docs/5.0/authentication#retrieving-the-authenticated-user
It is ok to validate auth in the middleware. In my application we are using the same functionality to check if user sends the right access_code to access to the API methods. Even Laravel itself handles protected routes by Authenticate middleware.
The problem is, there is no silver bullet of how or where to store additional data.
One method is to store this in the user's session.
The second is to use Illuminate\Foundation\Application class itself. You can inject it into your middleware __constructor() and use it to save your data. Application class extends Container class that implements ArrayAccess interface that allows you to access to it's properties like it is an array. That allows you not only to get variables from the Application but to store them too. Not the best way though the simplest.
public function __construct(\Illuminate\Foundation\Application $app)
{
$app['_foo'] = 'bar';
}
There are more such hacks but these are the simplest.
Related
I think i have a rough idea of what a guard does. for some reason there's not really much write-up about it online. I saw this line of code in someones middleware
public function __construct(Guard $auth)
{
$this->auth = $auth;
}
and i don't understand what it does. i understand that there two types of inbuilt guards-web and api and web is the default guard. What does the "Guard" inside the construct do? and how does the $auth variable come into play?.
here's the pic of the full code
The Guard class is used for authentication i.e. logging a user in, checking to see if there is an authenticated user, retrieving the authenticated user, logging them out etc.
I'd say the most common way to access this information (going off the docs and various tutorials) is by using either the Auth Facade or the auth() helper function. With either approach you will have access to the same methods e.g.
auth()->user() or Auth::user() will return the current authenticated user.
auth()->id() or Auth::id() will return the current authenticated user's id.
auth()->check() or Auth::check() will tell you if the current user is logged in or not.
etc.
In either case (using auth()-> or Auth::) you're going to accessing methods on the Guard class.
Laravel also has something called the Service Container which is a way for you to be able to have dependency injection. This is essentially where you can get an instance of a class automatically without having to do something like new ClassName(). This might not seem like a big deal at first but if you have a class that needs to be passed different variable and classes to its constructor you can set this up in the container so you don't have to worry about it. Another benefit might be that you want to use the same instance of a class rather than creating a new one each time which is something that can be done with the container as well.
Now, some people prefer to use dependency injection instead of using Facades or helper functions (see here for more information). With the case in your example you're injecting the Guard class so that you can access it as a property on the class rather than using the Facade or helper function. There isn't more to it than that.
I was looking through the built in auth controllers and I noticed they use something called "Guards". Up until now whenever I made my own logins/register forms I never touched these and would usually just do things like:
Auth::attempt()
without any type of guard. I've tried looking up what exactly it is but I couldn't really find any information on it, could someone explain to me what the purpose of the guards are?
They're the definition of how the system should store and retrieve information about your users.
You can find the configuration in your config/auth.php file. A web guard is the traditional cookie store - so that web guard instructs Laravel to store and retrieve session information the classic way. The API guard, on the other hand, uses tokens. So you would use the API guard if you want to authenticate users and requests using an API token in the header (bearer) or query parameter.
You can also create your own guard if you wish, and there's also this good introductory blog post on the topic by Matt Stauffer.
Since I had the same question and the other answers did not provide me the information I was looking for (they explain perfectly what a guard does, but not why you should ever worry about calling its methods), I will provide another answer.
I was also unsure about the difference between methods provided by the auth() helper and methods provided by the guard itself auth()->guard(), as they seemed to do the same.
A quick dd(auth()) reveals that it returns an instance of AuthManager. So we can look up that class in the source code: On the bottom of AuthManager.php there is a __call() magic method which forwards all undefined calls to its own guard() method.
public function __call($method, $parameters)
{
return $this->guard()->{$method}(...$parameters);
}
This clearly shows us that the methods of auth() and auth()->guard() not only seem to do the same, but are exactly the same. So as long as the default guard should be used, an additional ->guard() can be omitted with peace of mind.
A guard is a way of supplying the logic that is used to identify authenticated users. Laravel provides different guards like sessions and tokens. The session guard maintains the state of the user in each request by cookies, and on the other hand, the token guard authenticates the user by checking a valid token in every request.
Guard role is to authenticate routes
Web guard will authenticate web routes
Api guard will authenticate api routes.
For other user types e.g Admin guard will authenticate admin routes and so on.
I'm a bit confused on how to perform insert and update statements using MVC.
Is it ok to create an instance of an object in your controller and pass it to your service to save it or do you pass data to your service and handle everything else in there?
Insert
In my controller something like:
$userservice->insert("myname","mypassword");
In my UserService:
function insert($username,$password){
$user = ORM::for_table('user')->create();
$user->username= $username;
$user->password= $password;
$user->save();
}
Update
In my controller something like:
$userservice->update("myname","mypassword",1);
In my UserService:
function insert($username,$password,$id){
$user = ORM::for_table('user')->find($id);
$user->username= $username;
$user->password= $password;
$user->save();
}
Is this good practice?
Because I see a lot of these answers where for example a user is being created in the controller and passed to a repository to save it:
Proper Repository Pattern Design in PHP?
But I don't like the idea of creating a user in the controller...
Controllers belongs to application layer and controlls only activity. In your example the activities are Create- and Update for an existing or for a new User. These operations belongs to the Domain Layer, which contains services. Thus services encapsulate the domain as a gatekeeper and provides operations for resolving domain like a facade.
Is it ok to create an instance of an object in your controller and pass it to your service to save it or do you pass data to your service and handle everything else in there?
The service should provide a method to pass a ValueObject. ValueObjects are better to encapsulate lot of data (Property values for User). Inside the service, the ValueObject should be delegated to Filter and Validator. If validation didn't fail the ValueObject will be delegated to a DataMapper. The DataMapper will map the properties of ValueObject to a data-model for the UserRepository (ORM). Repositories often need another model of data, e.g. Objects versus storage mediums based on RDBMS like MySQL.
This approach should be strict to seperate the concerns between layers to improve maintainabilty and interchangeabilty. Services should be thin and acts as a delegator to Domain Objects (Filter, Validator, etc.), for example see Service Layer Pattern.
So, where should be a value object created?
I would prefer that the service provides a method for this: getEntityPrototype() by using the prototype pattern.
Be careful with naming. ValueObject is an object which have no identity. Entity is an object with identity (here id of User). For an existing User you will have have a method like getUserById($id), which should return an UserEntity. If User does not exist for given id, it should return a NullObject. To create a new User getEntityPrototype() will return an UserEntity which have no identity yet, so you will call it ValueObject or better Prototype of Entity. After setting properties (e.g. by a FormObject) and persisting this object is a real entity. In a Factory for this service you can set the EntityPrototype.
What you should think about in this case is if the classes have only one responsibility.
Controller decides about the flow of the action. If there's a need for registering a user then it registers him, but it should not define how to do it, but ask a service to complete this task and get the result.
On the other hand you should have some kind of UserManager which updates, creates and fetches users - is this single responsibility? Kinda, yes - it's managing them in a broad sense.
There's a slight problem you have with your methods' names though. You should have registerUser not insert since it's way easier to tell what it actually does.
You should Pass Data to Model. MVC is all about dividing tasks Controller - Handles Application Flow, Model - Contains all the business login Database etc and View - here you decide how to show. Basically the UI part is stored here
So the Controller should send data to Model and model decides what to do with the data. The advantage of coding this way is that in future if you want to change something in the code you know where to look, or if you ask a designer to redesign your website you only have to give him the VIEW part of code . If the designer does something that caused an error , correcting that wont take that much time. If you follow MVC properly Adding,Updating or Maintaining functionality wont be a problem
While testing roles in my application I found the function isGranted of the SecurityContext. It works great but now I need to check the roles of a user that is not the current user so isGranted doesn't work for me.
I've been looking and I found the function hasRole of the user, the problem is that this function doesn't look in the hierarchy tree of Symfony and it just looks in the roles assigned to the user.
So, Is there a function that looks for a role of a user looking in the hierarchy tree like isGranted do for the current user?
EDIT
I found this solution:
How to use the AccessDecisionManager in Symfony2 for authorization of arbitrary users?
I implemented it and it works, the problem is that it needs the ContainerBuilder and I would prefer a different approach.
Any Idea?
Basically AFAIK SecurityContext work with Symfony\Component\Security\Core\Authentication\Token\TokenInterface from where can fetch current user using getUser method.
If user token is not authenticated then isGranted trying authenticate user token first and then use class called AccessDecisionManager which basically iterate over voters objects and call them (and can use different strategies for that) One of called voters is RoleHierarchyVoter which use Symfony\Component\Security\Core\Role\RoleHierarchy.
So answer to your question:
I think that is no such function like isGranted for other users (or do not know about any), but you can write own service which allow to that using security.role_hierarchy (just notice that is private service).
BTW hasRole probably should be sufficient most of the time, so maybe you should think about what do you want to do ;)
I'm in the process of reorganizing an application.
At the start of my application I need an object to be initialized to represent the current user. I am planning an authentication class to handle logging in and logging out, and I am wondering if the initial session variable check for user id and database retrieval would be appropriate for this class as well or if there is a standard protocol?
Thanks
Well, Of Course. Checking the session variables for user id at first is the right thing to do.
No matter what kind of authentication use, at a point you have to check if someone is already logged in or not. It is not even that complicated. For the simplest of use:
if(isset($_SESSION['logged_status']) && $_SESSION['logged_status'] ==1) {
$this -> logged = true;
}
However, the database retrieval part as a session variable is not as secured as you want it to be. Although, caches records can be stored in the session without any risk.
Well typically the way i do it is to create a generic WebUser class. This calss is basically the model for the session. So everytime the app runs an instance of it is created. Then on that class ill dop methods like signIn/signOut, isAuthenticated and other things. This class then interacts with the model for authentication which also returns certain attributes of a User entity (like the user_id) for use later. Though i also usually make a convenience getter for the User entity directly on the WebUser class.