Laravel - check account status when Perform post request - php

in my user table I have a active_id column to track this user account is still active or not.
Is it possible when a logged in user visit our website, check if it's not a active user then logout the logged in user.
Or when the logged in inactive user perform a post request , log out the user immediately .
Is it possible ?

You can accomplish this very easily with Middleware
Do the console command php artisan make:middleware CheckUserIsActive
Go to the generated file at app/Http/Middlewares/CheckUserIsActive
In the handle method
public function handle($request, Closure $next)
{
if (! $user = auth()->user()->is_active) {
auth()->user()->logout();
}
return $next($request);
}
Edit the app/Http/Kernel.php file: find web key on middlewareGroups property and append your new middleware \App\Http\Middlewares\CheckUserIsActive::class,
With this approach the check will be fired off on each request on your app, assuming that in your routes.php file you have web group middleware applied to all your routes, which is the case if you installed laravel and didn't change it.
Take a closer look at middlewares in the Documentation
Also note, that this will work only when there is an authenticated user. If there isn't then auth()->user() will return null and you'll get and error like 'Trying to call method logout() on null'. To avoid this error you need to make sure that there is an authenticated user and only then check if he's active. To do so Laravel provides built in auth middleware. Just append it to the middlewaresGroups's web key before your own middleware.
But again this is to work if it's fit your projects needs. If you do require user to be authenticated to go to any of the pages of your app then do this approach. if not - you need to limit some requests to be filtered by middlewares. Again, you may find this on docs or ask here if needed, I'll provide samples

Related

Middleware laravel

I am new in laravel and I have one problem with middleware. On official laravel site, I found code for creating controller.
When I creating controller it is recommended to add middleware in constructor or this is only if I need some additional functionalities?
Also, if I include auth middleware, did I get some benefits by default, like security checks or similar or I must to rewrite middleware code first?
class UserController extends Controller {
/**
* Instantiate a new controller instance.
*
* #return void
*/
public function __construct() {
**//this part includes some protection or similar by default ?**
$this->middleware('auth');
}
}
Middleware is used when you want to filter the HTTP requests entering your application.
For example, including the built-in auth middleware will restrict non-authenticated users from accessing a page and redirect them to the login screen.
You can include middleware into your controller and routes.
In the controller you do it like so:
public function __construct()
{
$this->middleware('auth');
}
For a route you do this:
Route::get('/page', 'MyController#myMethod')->middleware('auth');
Do I need to include this part of code when I creating controller or not ?
As I said in my comment, it really depends on the desired functionality whether you use it or not.
An example
Your homepage should probably be accessible for anyone who visits you website, while your dashboard should only be displayed to authenticated users.
That's where you would include the auth middleware.
Question #1
Do you need to use $this->middleware('auth'); in your controller?
Answer: Only if you want to protect all of the methods of that controller from non-authenticated users and only allow signed in users to access controller actions.
Question #2
Do you get benefits for using the auth middleware?
Answer: Yes you do, only authenticated users can access the controller or routes protected by auth.
** Question #3**
Do you need to write your own middleware?
Answer: Only if you need to override a middleware or need extra functionality that is not already provided (php artisan make:auth), but if you are rolling your own login functionality then you will likely need/want to create your own middleware.
Resources:
Look in App\Http\Kernel.php and you will see that the $routeMiddleware array matches the auth middleware to the \Illuminate\Auth\Middleware\Authenticate::class which actually verifies that the current user is logged in and allows them to pass, if they are not logged in then it will redirect them to the '/login' route.
You will see that Laravel uses quite a bit of middleware by default, such as starting the session, encrypting cookies and protecting against CSRF forgery.
There are several ways to implement middleware, which I'm sure you saw in the docs.
Some Helpful Video Tutorials:
I suggest you watch each of the free series usually titled Laravel from Scratch on Laracasts.com. I would also suggest watching all of from Laravel 5.7 back to 5.1 or 5.0 as Jeffrey Way may use different techniques in similar situations and it will provide you with a great tips and helpful information as to how things work along with some Laravel best practices along the way. I've subscribed to him for years and work in Laravel everyday and I still learn some new things from watching his videos, a subscription is easily worth 10-20 what he charges.

Laravel Broadcast authentication

How do I authenticate an user to a channel with a custom auth method?
For example, in my app I use a token auth (stored in the db for each user) for my API, passed via header and read by a custom middleware.
How do I control the access with these custom auth methods for channels? How would be the client and server side? I am using socket.io and the Laravel docs are quite unclear of how auth methods works for sockets.
USE CASE:
I have users stored in DB with default Laravel migration. However, how my app is just the API, it is stateless, then, rather than using remember_token to store session tokens, I use it to store an unique authentication token, generated in the login endpoint.
Every endpoint of the API, the request pass through a middleware, where the user is retrieved by the token present in the headers
$token = Request::header('X-token');
$request->user = User::findByToken($token);
return $next($request);
Now the question comes in. Laravel docs isn't much clear on how private channels works.
How would a broadcast client pass the mentioned token and get authorized to join a given channel?
The Laravel documentation on broadcasting is pretty comprehensive about this, although it doesn't go into minute detail on client libraries that it doesn't support out of the box.
In this case, you're wanting the section on authorizing channels. From the docs:
In the BroadcastServiceProvider included with your Laravel application, you will see a call to the Broadcast::routes method. This method will register the /broadcasting/auth route to handle authorization requests
When defining broadcast routes, the currently authenticated user is passed automatically as a parameter. Since you're wanting to change the authentication mechanism ahead of the broadcast route definition so that the correct user is passed along, your broadcast client would pass along the token (however you like - HTTP header, URL parameter, POST data, etc.) and then you would customise the /broadcasting/auth route to parse that data and use it to authenticate the user. From there you would use the standard Broadcast::channel() definitions to ensure that the authenticated user is also an authorized user on that channel.
As per the documentation, Broadcast::routes() takes an optional array of $attributes for it to use the web middleware. From the source:
$attributes = $attributes ?: ['middleware' => ['web']];
So if you wish, you may change the middleware authentication to 'api' by passing it to the Broadcast::routes() call (or any other standard route parameters).
Since the route is already created for you, if you want to customise it at a lower level that route functions/middleware then you would need to change the auth() method on whichever BroadcastProvider you're using. More specifically, when the route is set up, it calls the authenticate() method on the BroadcastController, which in turn simply calls the auth() method on the Broadcast facade. The facade would then call whichever provider you're using - there are a few providers defined out of the box which should give you a good starting point if you want to write your own. That being said, as long as you don't have a problem with the provider itself, it's probably easier to just write your own middleware and pass that to Broadcast::routes() as an attribute if you need something particular with your authentication (if it differs from the api authentication middleware).
As an extra, since you've tagged this with socket.io, you may also want to read up on Laravel Echo. There's also a section on talking to socket.io specifically in the broadcasting introduction.
On top of Leith's answer, those scratching head and wondering why creating a custom middleware and using it in BroadcastServiceProvider.php would throw back an error.
public function boot()
{
Broadcast::routes(['middleware' => ['custom.middleware']]);
require base_path('routes/channels.php');
}
Inside Broadcaster.php there is a method called retrieveUser() which should return $request->user() as a result of successful authentication from within your custom middleware.
In my case, I was trying to pass access token to API's custom middleware; and once authenticating the user, I simply passed on my original request return $next($request)
For the above code to work, I had to fetch the user model by access token and then merge it to the original request like so
$request->merge(['user' => $user ]);
$request->setUserResolver(function () use ($user) {
return $user;
});
return $next($request);
So now retrieveUser() method from Broadcaster.php is able to retrieve the authenticated user with return $request->user() command, and it gets passed to Broadcast::channel method as a first parameter
Broadcast::channel('private-channel-name', function ($user) {
// if you get here, you've been authenticated (within a custom middleware)
return true;
});

Laravel 5.4 Passport Log user action (Optional auth:api)

I am using Laravel Passport (auth:api), all works well however I've came with the idea to log record user requests on a specific route.
When an GET request is made to /movie/65 I would like to store in movie_view the following data: user_id, movie_id (if the user is logged in)
However in my controller I am unable to call $request->user() without setting auth:api middleware.
What is the best practice you recommend to achieve this?
Default Auth Type should be set to 'api' in config/auth.php
Source: https://laracasts.com/discuss/channels/general-discussion/optional-authentication-for-api?page=0 (it was very hard to find)
Best way to do this is:
if (\Auth::guard('api')->check()) {
$user = \Auth::guard('api')->user();
}
you have to setup the guard to 'api', the default one is 'web'.
You can create a custom middleware as suggested here -- https://laracasts.com/discuss/channels/laravel/how-to-handle-route-with-optional-authentication. Then apply api guard to it. Let say you assign that custom middleware as auth.optional in Kernel.php, then you can use that middleware as auth.optional:api (with that api guard). Then you can access user thru $request->user() in your case above.

Laravel - Authentication via external API

Firstly I'm a real beginner with Laravel so I will try to describe my problem as best as I can.
I am building a website using Laravel however the information on users will not be stored on my server but rather externally on another server.
The only way to access the user's data is through an external API; I am not allowed access to their database. The API request returns a token and I use this token to check with their server to see if the user is logged in.
My question is: how do I authenticate the user so that I can still use Laravel's out of the box guards.
It's really handy to use methods like Auth::check() to determine if the user is still logged in.
You'll either need to modify Laravel's default authentication middleware in app/Http/middleware/Authenticate.php or you'll need to create your own middleware class that runs the authentication that you need. Create a class in the app/Http/middleware folder and register that middleware. https://laravel.com/docs/master/middleware

Laravel: Difference Between Route Middleware and Policy

Developing an app with laravel I realised that what can be done with Policy can exactly be done with Middleware. Say I want to prevent a user from updating a route if he/she is not the owner of the information, I can easily check from the route and can do the same from the policy.
So my question is why should I use policy over middleware and vice versa
I'm currently going through a small refactor with my roles, permissions and routes and asked myself the same question.
At the surface level, it appears true middleware and policies perform the same general idea. Check if a user can do what they are doing.
For reference here's the laravel docs...
Middleware
"May I see this? May I go here?"
HTTP middleware provide a convenient mechanism for filtering HTTP
requests entering your application. For example, Laravel includes a
middleware that verifies the user of your application is
authenticated. If the user is not authenticated, the middleware will
redirect the user to the login screen. However, if the user is
authenticated, the middleware will allow the request to proceed
further into the application.
Of course, additional middleware can be written to perform a variety
of tasks besides authentication. A CORS middleware might be
responsible for adding the proper headers to all responses leaving
your application. A logging middleware might log all incoming requests
to your application.
https://laravel.com/docs/master/middleware#introduction
In my reading, Middleware is about operating at the request level. In the terms of "Can this user see a page?", or "Can this user do something here?"
If so, it goes to the controller method associated with that page. Interestingly enough, Middleware may say, "Yes you may go there, but I'll write down that you are going." Etc.
Once it's done. It has no more control or say in what the user is doing. Another way I think of it as the middleperson.
Policies
"Can I do this? Can I change this?"
In addition to providing authentication services out of the box,
Laravel also provides a simple way to organize authorization logic and
control access to resources. There are a variety of methods and
helpers to assist you in organizing your authorization logic, and
we'll cover each of them in this document.
https://laravel.com/docs/master/authorization#introduction
Policies however, appear to be more concerned with doing. Can the user update any entry, or only theirs?
These questions seem fit for a controller method where all the calls to action on a resource are organized. Retrieve this object, store or update the article.
As tjbb mentioned, middleware can make routes very messy and hard to manage. This is an example from my routes file:
The problem
Route::group(['middleware' =>'role:person_type,person_type2',], function () {
Route::get('download-thing/{thing}', [
'as' => 'download-thing',
'uses' => 'ThingController#download'
]);
});
This gets very hard to read in my route file!
Another approach with policies
//ThingController
public function download(Thing $thing)
{
//Policy method and controller method match, no need to name it
$this->authorize($thing);
//download logic here....
}
Route middleware allows you to apply request handling to a large range of routes, instead of repeating the code in every controller action - checking authentication and redirecting guests is a good example. Controllers instead contain logic unique to specific routes/actions - you could use middleware for this, but you'd need separate middleware for every route's logic and it would all get very messy.
Policies/abilities are simply a way of checking user permissions - you can query them from a controller, or from middleware, or anywhere else. They only return true or false, so they aren't equivalent to controllers or middleware. Most of the time abilities will be comparing a user to another model, which will have been loaded based on an identifier sent to a controller action, but there are probably some applications for use with middleware too.
I have asked myself the same question. In practice, I predominantly use middleware.
My most common usage is when authorisation is only allowed for a specific user, for instance:
public function update(User $user, user $model)
{
return $user->id === $model->id;
}
Though, even in the instance above, Yes, one could do without it and write their own logic in the controller to do the same thing.
I also like the before method, which I use to allow the administrator full-privileges for a model, for example:
public function before($user, $ability)
{
if ($user->admin === 1) {
return true;
}
}
The main reason, though, why I have started to use Policies on some Laravel projects is because of what you can do with blade. If you find yourself setting permissions numerous times for the same user authorisation in your blade files, for example, to show an edit button, then Policies may become very useful because you can do the following with them (and more):
#can('update', $post)
<button class="btn btn-primary">Edit Post</button>
#endcan
#cannot('create', App\Models\Post::class)
<div class="alert alert-warning">You are not allowed to create a post</div>
#endcannot
I sometimes find these Policy-referencing blade methods to be super useful, when wanting to group authorisation in one place.

Categories