Laravel What is a guard? - php

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.

Related

Can someone explain what this code does in laravel

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.

Why use guard in laravel?

I have recently started using laravel 5.2. I don't understand what's the use of guards. As I see everything that can be done with guard can easily be replaced with lot more readable middleware. Am I missing anything ?
Guard will let you to have multi authentication in your app and you we have diffrent provider even drivers(such as doctrine or eloquent). for example, you can have login with user model and an admin model in one application at the same time.
You may specify which guard instance you would like to utilize using the guard method on the Auth facade. This allows you to manage authentication for separate parts of your application using entirely separate authenticatable models or user tables.
The guard name passed to the guard method should correspond to one of the guards configured in your auth.php configuration file:
if (Auth::guard('admin')->attempt($credentials)) {
//
}
Know more about Illuminate/Contracts/Auth/Guard

Laravel 5 Multi-Factor Authentication

I'm looking at implementing two-factor authentication for one of my projects. I've seen: https://github.com/bitbeans/Yubikey
https://github.com/antonioribeiro/google2fa
https://github.com/lahaxearnaud/laravel-u2f
And I want to leave the choice up to my users, on which and how many methods of authentication will be required. As such I know I'm looking at coding something special to achieve this but I'm not sure where to start.
My goal is to enable users to not use any additional authentication methods or allow them to use all additional authentication methods available. Ideally the login form would only require username/password; upon entering correct credentials the user would be directed to a new page for every authentication method the user has chosen to use.
laravel-u2f uses middleware; which I'm not against doing, but seems like too much extra logic to process for every request instead of just when logging the user in.
I've thought about replacing the default Auth driver but I'm not sure that's the best thing to do.
My final thought; and what I'm leaning towards is listening for the "auth.attempt" event and using that to check what additional authentication needs to be done. But I'm not sure how the best way to process getting additional authentication information from that.
So the reason I'm posting is looking for input on the best way to achieve what I'm looking for.
You could place a value e.g. full_authenticated
Session::put('full_authenticated', 'false');
and use it in the existing authentication middleware.
This way you cut the logic in the middleware section to one comparison.
If you want to add later more methods for authentication you should implement an interface/contract for a general authentication method.
Then you write a authentication manager class which sets full_authenticated in the session and handles the different methods for the different users.

Is it advisable to bind application data to request in Laravel 5

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.

Where to place the authentication logic in Laravel?

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.

Categories