Efficient update of the table field on each request - laravel

I want to update the user table field on each request if the user is authorized. I have not encountered such a task before. I tried to write on the AppServiceProvider.php file:
public function boot()
{
if(Auth::id()) {
$user = User::find(Auth::id());
$user->updated_at = Carbon::now()->setTimezone("America/Los_Angeles");
$user->save();
}
}
But in this case I could not take access to the authorized user.
Can I get access to the service provider to an authorized user?
Or solve this problem with creating middleware?
Note: I am doing this task to find out the time of the user's last activity.
Is the solution found right? Is there a load on the server?

by creating a new middleware try this one
php artisan make:middleware UserActivityUpdateMiddleware
UserActivityUpdateMiddleware
<?php
namespace App\Http\Middleware;
use Closure;
class UserActivityUpdateMiddleware
{
/**
* Handle an incoming request.
*
* #param \Illuminate\Http\Request $request
* #param \Closure $next
* #return mixed
*/
public function handle($request, Closure $next)
{
if(Auth::User()) {
$user = User::find(Auth::user()->id);
$user->updated_at = Carbon::now()->setTimezone("America/Los_Angeles");
$user->save();
}
return $next($request);
}
}

Related

Trying to get property 'status' of non-object

I want create role admin and member in login multi user laravel
My Code in Middleware CheckStatus (chek role)
<?php
namespace App\Http\Middleware;
use Closure;
use App\User;
class CekStatus
{
/**
* Handle an incoming request.
*
* #param \Illuminate\Http\Request $request
* #param \Closure $next
* #return mixed
*/
public function handle($request, Closure $next)
{
$user = \App\User::where('email', $request->email)->first();
if ($user->status == 'admin') {
return redirect('admin/dashboard');
} elseif ($user->status == 'member') {
return redirect('member/dashboard');
}
return $next($request);
}
}
When I process login , I've get error Trying to get property 'status' of non-object
Please check the users table, is there any user which not belong to any role. Assign the rule to each user then it will work perfectly.
You can check the relation using tinker
php artisan tinker

Single API use for authenticated and guest user

My laravel application route configured on routes/api.php is.
<?php
use Illuminate\Http\Request;
Route::post('see_all_product', 'API\ProductController#see_all_product');
?>
Issue is i want to sent list of product but if user authenticated then send product favorite flag 1, and if not authenticated then send return favorite 0
But both case send product list with favorite flag.
If i logged in with my user id and password and send request for see_all_product that time i m getting blank user.
$user = $request->user();
But if i set route like below i m getting user details.
<?php
use Illuminate\Http\Request;
Route::group(['middleware' => 'auth:api'], function(){
Route::post('see_all_product', 'API\ProductController#see_all_product');
});
?>
Now issue is how can i get details if authorization set in the header with same api.
<?php
use Illuminate\Http\Request;
Route::post('see_all_product', 'API\ProductController#see_all_product');
?>
My see_all_product Function
public function see_all_product(Request $request){
try {
$user = $request->user();
} catch (Exception $ex) {
Log::error($ex);
}
}
API is same for both authenticated and guest user.
I pass authorization token in both case but middleware route i get user details but non middleware route i dont get user information.
Please guide me where i can miss something?
I think you can do it by the way instead of $request->user():
if (auth('api')->check()) {
$user = auth('api')->user();
}
Turn off ['middleware'=> 'auth:api']
use: $request->user('api'); in your controller.
Guests can use the api but user is null;
Auth users can use api as a real user.
alt:
Auth::guard('api')->user();
auth('api')->user();
I didn't test this method on old versions of Laravel, but it should work just fine on the latest ones.
You can create another Middleware that allows ether authenticated or guest users to proceed.
If the user is authenticated then the middleware will prepare the Auth object and auth() function for you.
<?php
namespace App\Http\Middleware;
use Closure;
use Illuminate\Contracts\Auth\Factory as Auth;
use Illuminate\Http\Request;
class AuthOptional
{
/**
* The authentication factory instance.
*
* #var \Illuminate\Contracts\Auth\Factory
*/
protected $auth;
/**
* Create a new middleware instance.
*
* #param \Illuminate\Contracts\Auth\Factory $auth
* #return void
*/
public function __construct(Auth $auth)
{
$this->auth = $auth;
}
/**
* Handle an incoming request.
*
* #param \Illuminate\Http\Request $request
* #param \Closure $next
* #return mixed
*/
public function handle(Request $request, Closure $next, ...$guards)
{
$this->authenticate($request, $next, $guards);
return $next($request);
}
/**
* Determine if the user is logged in to any of the given guards.
*
* #param \Illuminate\Http\Request $request
* #param array $guards
* #return void
*
*/
protected function authenticate($request, $next, array $guards)
{
if (empty($guards)) {
$guards = [null];
}
foreach ($guards as $guard) {
if ($this->auth->guard($guard)->check()) {
return $this->auth->shouldUse($guard);
}
}
//If unauthenticated allow the user anyway
$this->unauthenticated($request, $next, $guards);
}
/**
* Handle an unauthenticated user.
*
* #param \Illuminate\Http\Request $request
* #param array $guards
* #return void
*
*/
protected function unauthenticated($request, $next, array $guards)
{
return $next($request);
}
}
Import the newly created Middleware under app/Http/kernel.php
protected $routeMiddleware = [
....
'auth.optional' => \App\Http\Middleware\AuthOptional::class
];
And finally use it like this:
<?php
Route::group(['middleware' => ['auth.optional:api']],
});
?>
Now auth()->user() will return the user if user is authenticated and
null if it's not

Laravel multiple parameters in Route middelware not working

I have problem that using multiple parameters in my Route::middleware isn't working for me. I am trying to assign a specific route only accessible for a superuser and admin role.
When I just use:
role:superuser
it works fine, but when I add a second parameter like:
role:superuser,admin
it fails when I assign myself the admin role but still works for the superuser role.
I am confused so any help would be appreciated!
Here is my RoleMiddleware:
namespace App\Http\Middleware;
use Closure;
class RoleMiddleware
{
/**
* Handle an incoming request.
*
* #param \Illuminate\Http\Request $request
* #param \Closure $next
* #param string $roles
* #return mixed
*/
public function handle($request, Closure $next, ...$roles)
{
$user = $request->user();
if ($user && $user->isSuperuser($roles)) {
return $next($request);
}
return redirect('/home')->withError('U heeft niet de juiste rechten!');
}
}
Here is my isSuperuser method in my User model:
public function isSuperuser(...$roles)
{
if ($roles) {
return $this->roles == $roles;
}
return $this->roles;
}
Last but not least my routes/web code for the middleware:
Route::get('/users', 'UsersController#index')->middleware(['role:superuser,admin']);
Btw: the method is called 'isSuperuser' but that's just a name. It also has to accept the admin role at some point.
use | instead of , like this:
Route::get('/users', 'UsersController#index')->middleware(['role:superuser|admin']);

New registered user to be redirected to the password reset screen

I'm quite new to Laravel and have been stumped on a problem for 2 days - I'd be grateful for some guidance.
I'm using the default out-of-the-box User authentication system with Laravel 5.3. A new user is created automatically behind the scenes by an existing Admin user - I will in time hide the user registration page. I have also successfully set up middleware to check if a user is newly registered (by looking for a null 'last_logged_in_date' that I've added to the migration).
All I want to happen is for a new registered user to be redirected to the password reset screen that ships with Laravel (again, in time I will create a dedicated page). I would like this to happen within the middleware file. So far, my middleware looks like this:
<?php
namespace App\Http\Middleware;
use Closure;
use App\Http\Controllers\Auth;
class CheckIfNewUser
{
/**
* Handle an incoming request.
*
* #param \Illuminate\Http\Request $request
* #param \Closure $next
* #return mixed
*/
public function handle($request, Closure $next)
{
$user = $request->user();
if (! is_null($user->last_logged_in_date )) {
return $next($request);
}
// This is where I'm stuck!!!
}
}
I'm not sure what code to enter at the location indicated by the comments above. I've tried sendResetLinkEmail($request); etc and have imported what I though were the correct classes but I always end up with a Call to undefined function App\Http\Middleware\sendResetLinkEmail() message irregardless of what I 'use' at the top of my class.
Where am I going wrong? Thanks!
Well that happens because you have not defined your sendResetLinkEmail($request) function yet. You can do it like this, or you can create a new class with that and then call the class.
Call the trait SendsPasswordResetEmails and then access it with $this since traits are not classes and you cannot access their members directly.
<?php
namespace App\Http\Middleware;
use Closure;
use App\Http\Controllers\Auth;
use Illuminate\Foundation\Auth\SendsPasswordResetEmails;
class CheckIfNewUser
{
use SendsPasswordResetEmails;
/**
* Handle an incoming request.
*
* #param \Illuminate\Http\Request $request
* #param \Closure $next
* #return mixed
*/
public function handle($request, Closure $next)
{
$user = $request->user();
if (! is_null($user->last_logged_in_date )) {
return $next($request);
}
// This is where I'm stuck!!!
//EDIT
//return $this->SendsPasswordResetEmails->sendResetLinkEmail($request);
return $this->sendResetLinkEmail($request);
}
}

Middleware and user - laravel 5

How can i assign middleware to user? I just follow the guide on laravel 5.2 but i can't figure...
I'm able to create middleware ( i have admin middleware)
<?php
namespace App\Http\Middleware;
use Closure;
class Admin
{
/**
* Handle an incoming request.
*
* #param \Illuminate\Http\Request $request
* #param \Closure $next
* #return mixed
*/
public function handle($request, Closure $next)
{
return $next($request);
}
}
I'm able to assign middleware to route
Route::group(['middleware' => ['auth', 'admin']], function () {
Route::resource('admin/tasks', 'Admin\\TasksController');
});
but how can i check if user is admin or not? I just follow the docs on laravel 5.2 for authentication, but i dont know how to access the page only for "admin" middleware...
Question 1 How to check if user is admin
I think using session is a good solution. You can store the user status in the session. And in the Admin middleware, you can check if user is admin by if (session('statut') === 'admin').
Question 2 Page Access of users
If user is admin, we will pass the request by return $next($request);
If user is not admin, we will redirect to index page or other page
you want by return new RedirectResponse(url('/'));
The following code may help you.
<?php namespace App\Http\Middleware;
use Closure;
use Illuminate\Http\RedirectResponse;
class Admin {
public function handle($request, Closure $next)
{
if (session('statut') === 'admin')
{
return $next($request);
}
return new RedirectResponse(url('/'));
}
}
I would recommend you to use ENTRUST Laravel package
Entrust is a succinct and flexible way to add Role-based Permissions
to Laravel 5.
I have a small example for you, it very simple
<?php
namespace App\Http\Middleware;
use Closure;
use Illuminate\Contracts\Auth\Factory as Auth;
class Authenticate
{
/**
* The authentication guard factory instance.
*
* #var \Illuminate\Contracts\Auth\Factory
*/
protected $auth;
/**
* Create a new middleware instance.
*
* #param \Illuminate\Contracts\Auth\Factory $auth
* #return void
*/
public function __construct(Auth $auth)
{
$this->auth = $auth;
}
/**
* Handle an incoming request.
*
* #param \Illuminate\Http\Request $request
* #param \Closure $next
* #param string|null $guard
* #return mixed
*/
public function handle($request, Closure $next, $guard = null)
{
if ($this->auth->guard($guard)->guest()) {
return response('Unauthorized.', 401);
}
return $next($request);
}
}
If you only have guest and admin(who is authenticated in your system) you should do like above. But if you have another roles you will have to attach ACL (for ex https://github.com/Zizaco/entrust)

Resources