In Laravel 5.2, I have added has_login field in the users table.
Where do I add logic to prevent user logging in if has_login is value 0 in the users table? I use AuthController.php for authentication and use AuthenticatesAndRegistersUsers without using login() / authenticate() functions in AuthController.hp file. Login work fine.
I personally tend to do this in the middleware, but you can also do it outside of that.
Here's a middleware example:
<?php namespace App\Http\Middleware;
use Closure;
use Illuminate\Support\Facades\Auth;
class RequireHasLogin
{
/**
* 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 (Auth::guard($guard)->check())
{
if (!Auth::guard($guard)->user()->has_login)
{
Auth::logout();
if ($request->ajax() || $request->wantsJson())
{
return response('Unauthorized.', 401);
}
return redirect()->guest('/auth/login');
}
}
return $next($request);
}
}
Though I think some people do this too:
Auth::guard()->attempt(["email" => $email, "password" => $password, "has_login" => true])
This should point you in the right direction -
https://laravel.com/docs/master/authentication#authenticating-users
Related
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
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
In the email verification routes, I wanted to change the route by adding the language in the URL. e.g., instead of having /email/verify, we want to have /fr/email/verify.
Route
// Email Verification Routes
Route::get('{lg?}/email/verify', 'Auth\VerificationController#show')
->name('verification.notice')
->where('lg', '(fr)|(en)');
In the EnsureEmailIsVerified class, the users are to the "verification.notice" route:
<?php
namespace App\Http\Middleware;
use Closure;
use Illuminate\Support\Facades\Redirect;
use Illuminate\Contracts\Auth\MustVerifyEmail;
class EnsureEmailIsVerified
{
/**
* Handle an incoming request.
*
* #param \Illuminate\Http\Request $request
* #param \Closure $next
* #return mixed
*/
public function handle($request, Closure $next)
{
if (!$request->user() ||
($request->user() instanceof MustVerifyEmail &&
!$request->user()->hasVerifiedEmail())) {
return $request->expectsJson()
? abort(403, 'Your email address is not verified.')
: Redirect::route('verification.notice');
}
return $next($request);
}
}
Sadly, Redirect::route('verification.notice') redirects to /email/verify instead of en/email/verify (or fr/email/verify). What did I miss?
I don't have access to my dev machine, but something along the lines of
Redirect::route('verification.notice', ['lg' => 'en'])
or
redirect()->route('profile', ['lg' => 'en']);
should work.
I modify the login function in Login controller using credentials function
protected function credentials(\Illuminate\Http\Request $request)
{
return ['email' => $request->email, 'password' => $request->password, 'status' => 1];
}
although the function is work, but i need to return an error message to show that "Account is suspended" in login page if user's status not equal to 1.
How can i modify the error message?
You should make a middleware for that so you can use it. not only in your login function.
<?php
namespace App\Http\Middleware;
use Closure;
use Auth;
class CheckStatus
{
/**
* Handle an incoming request.
*
* #param \Illuminate\Http\Request $request
* #param \Closure $next
* #return mixed
*/
public function handle($request, Closure $next)
{
if (Auth::user()->status != 1) {
return redirect('yourloginpageroute')->withInfo("Account is suspended");
}
return $next($request);
}
}
Assuming that you have a status row in your auth.
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)