I used the laravel spatie backup in my system, and all my functions such as creating a new backup, deleting, and downloading are working locally. I tried to deploy my website on a free hosting, everything seems to work except the delete and download function. Upon investigating, I have seen that it fails because of the Middleware I have created for the download/delete route. Here's my StaffMiddleware where only accounts with the staff role can access it.
Middleware
public function handle($request, Closure $next)
{
if(Auth::check())
{
if(Auth::user()->role == 'staff')
{
return $next($request);
}
else
{
return redirect('/');
}
}
else
{
return redirect('/');
}
}
Routes
Route::get('backup/create', 'Admin\BackupController#create');
Route::get('backup/download/{file_name}', 'Admin\BackupController#download');
Route::get('backup/delete/{file_name}', 'Admin\BackupController#delete');
When I try to access the download function, it redirects to the homepage since the Auth::check() line fails in my middleware. Note that I am logged in and authenticated while accessing the download function. This only happens in the live server, but all of the code works locally. Can you please help me on this one? Thanks!
can you try this
public function handle($request, Closure $next)
{
$user = Auth::user();
//dd($user); //debug if didn't work
if($user && $user->role == 'staff') // if your role is coming from relation then try `$user->role->name == 'staff'`
{
return $next($request);
}
return redirect('/');
}
I think you have to get the user from the request
public function handle($request, Closure $next)
{
if ($request->user() && $request->user()->role == 'staff')) {
return $next($request);
}
return redirect('/');
}
You can try this:
namespace App\Http\Middleware;
use Closure;
use Illuminate\Support\Facades\Auth;
class AdminMiddleware {
/**
* 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)->guest()) {
if ($request->ajax() || $request->wantsJson()) {
return response('Unauthorized.', 401);
} else {
return redirect('admin/login');
}
}else{
if( \Auth::user()->role =="admin" ){
return $next($request);
}
}
return redirect("admin/login");
}
}
Related
I am working on a project in which I have three type of users Admin and user1 and user2. I want user1 and user2 to able to use certain features in application only if the admin has assigned an invoice to them. I have tried using helper function given below.
$invoice = Invoice::pluck('user_id')->toArray();
if (Auth::user()->admin == 1 || in_array(Auth::user()->id, $invoice)) {
return 1;
} else {
return 0;
}
but this does not work fine. I'll have to place it before every method of a controller in order to restrains users to use that feature. Is there any thing else I can do?
Any Better Approach for this?
You can use middlewares.
Create your middleware with
php artisan make:middleware UserWithInvoiceMiddleware
Then open your file in app/Http/Middleware/UserWithInvoiceMiddleware.php, and add this to the handle method:
public function handle($request, Closure $next, ...$guards)
{
$user = auth()->user();
$invoice = Invoice::pluck('user_id')->toArray();
if ($user->admin || in_array($user->id, $invoice)) {
return $next($request);
}
return response()->json(['message' => 'Request not authorized.'], 401);
}
Also, you can create a relation in your user model with the Invoice model:
public function invoice()
{
return $this->hasOne(Invoice::class);
}
Then, you can simplify your middleware using this relation:
public function handle($request, Closure $next, ...$guards)
{
if (auth()->user()->admin || auth()->user()->has('invoice')) {
return $next($request);
}
return response()->json(['message' => 'Request not authorized.'], 401);
}
You have to register your middleware in app/Http/Kernel.php, under the $routeMiddleware array:
protected $routeMiddleware = [
...
'user-with-invoice' => App\Http\Middleware\UserWithInvoiceMiddleware::class,
];
Then, you can protect your routes with this middleware, adding a ->middleware('user-with-invoice') to the routes where the user has to be an admin or have an invoice:
Route::get('/example', ExampleController::class)->middleware('user-with-invoice');
you can use make a middleware and pass requests throw it to check if the user is authorized to do that or not.
class SomeMidllewareName
{
/**
* Handle an incoming request.
*
* #return mixed
*/
public function handle(Request $request, Closure $next)
{
$invoice = Invoice::pluck('user_id')->toArray();
if (1 == Auth::user()->admin || in_array(Auth::user()->id, $invoice)) {
return $next($request);
}
return \response()->json(['message' => 'you are not authorized'], 401);
}
}
then, you can validate on the routes and you can use also policies and validate every feature alone
I am trying to make a middleware which can filter my http request by checking if the "$created_by" that I am passing through the request alreday exists in my "users" table
If it does I want to proceed with my "$next($request)"
And if it doesn't I wanna redirect it.
When the situation is this:-
if ($ip->uuid == $request->created_by)
It redirects to $next($request); which is correct
But when the "$request->created_by" is not present in DB it which makes $ip null
And it shows this error "Trying to get property 'uuid' of non-object"
Here's my Middleware:-
<?php
namespace App\Http\Middleware;
use Closure;
use App\User;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\DB;
class Posts
{
/**
* Handle an incoming request.
*
* #param \Illuminate\Http\Request $request
* #param \Closure $next
* #return mixed
*/
public function handle($request, Closure $next)
{
$ip = DB::table('users')->where('uuid', '=', $request->created_by)->first();
// dd($ip);
if ($ip->uuid == $request->created_by) {
if ($ip == null) {
return redirect('https://www.google.com');
}
}
return $next($request);
}
}
you can use optional to prevent error if you object is null.
public function handle($request, Closure $next) {
$ip = DB::table('users')->where('uuid', '=', $request->created_by)->first();
if(optional($ip)->uuid == $request->created_by) {
return $next($request);
}
return redirect('https://www.google.com');
}
You have to make sure that $ip is not null before trying to access property uuid.
public function handle($request, Closure $next) {
$ip = DB::table('users')->where('uuid', '=', $request->created_by)->first();
if(is_null($ip) || $ip->uuid !== $request->created_by) {
return redirect('https://www.google.com');
}
return $next($request);
}
Edit:
You already made the comparison in DB, update handle() to be:
public function handle($request, Closure $next)
{
$ip = DB::table('users')->where('uuid', '=', $request->created_by)->first();
if (is_object($ip) {
return $next($request);
}
return redirect('https://www.google.com');
}
I have an auth login page which logs in and redirects to home.blade.php
I need here to check whether user_type in user table is admin or Normal. If user_type=='admin' redirect to home else redirect to home_user page.
Route.php
Route::get('/home', 'HomeController#index')->name('home');
Route::get('/home_user', 'HomeController#index')->name('home_user');
or
protected function redirectTo() {
if (Auth::user()->user_type == 'admin')
return '/home';
else
return '/home_user';
}
As defined in the comment you can also use middleware but it could be the tricky way to do that. You can override the following function in the loginController.
protected function authenticated(Request $request, $user)
{
if (Auth::user()->user_type == 'admin') {// do your magic here
return redirect('/home');
}
return redirect('/home_user');
}
For the reference you can visit here
Below code, I have used for same. Try this.
use Redirect;
protected function authenticated($request, $user)
{
if($user->is_admin == '1') {
return Redirect::to('home');
}elseif ($user->is_admin == '2') {
Auth::logout();
return Redirect::to('/admin/login');
}else{
return Redirect::to('studentDashboard');
}
}
You have already solved the problem, but you have 1 mistake in your code.
In laravel in order to redirect, you need to return redirect()->to() or redirect()->route() functions. all you need to do is replace your code with this:
protected function redirectTo() {
if (auth()->user()->user_type == 'admin')
return redirect()->route('home');
else
return redirect()->route('home_user');
}
Override the existing authenticated method from AuthenticatesUsers trait.
/**
* The user has been authenticated.
*
* #param \Illuminate\Http\Request $request
* #param mixed $user
* #return mixed
*/
protected function authenticated(Request $request, $user)
{
if (Auth::user()->user_type == 'admin')
return redirect('/home');
else
return redirect('/home_user');
}
Reference: authenticated method
i have problem with laravel cus im begginer but i work with php languge very well
and my Question:
I created a table for users in my database and create column for type
There are 3 user types in my table:
customers - Workers - Factories
How can i use middlewarre or anything else Prevent access to other pages
public function Signupuser(Request $request){
$email=$request['email'];
$username=$request['username'];
$tell=$request['mobilenumber'];
$pass=bcrypt($request['password']);
$status_reg=$request['status_register'];
$usertable=new UserTable();
$usertable->username=$username;
$usertable->email=$email;
$usertable->Password=$pass;
$usertable->Tell=$tell;
$usertable->StatusReg=$status_reg;
$usertable->save();
Auth::login($usertable);
if($status_reg=='factory'){
return redirect()->route('FactoryDashboard');
}
if($status_reg=='worker'){
return redirect()->route('WorkerDashboard');
}
if($status_reg=='customer'){
return redirect()->route('CustomerDashboard');
}
}
public function signinuser(Request $request){
$email=$request['email'];
$pass=$request['pass'];
if (Auth::attempt(['email'=>$email,'password'=>$pass])){
$status = Auth::user()->StatusReg;
return $status;
}
else{
return "nokey";
}
}
i used with one middleware but this middleware dosent work
<?php
namespace App\Http\Middleware;
use App\UserTable;
use Closure;
class WorkerMiddleware
{
/**
* 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()->StatusReg !='worker'){
return redirect('homepage');
}
return $next($request);
}
}
please help guys
Your scenario is usually dealt with by using the Authorization service of Laravel.
For example, you could add the following to your app\Providers\AuthServiceProvider.php file:
Gate::define('factory', function ($user) {
return $user->StatusReg == 'factory';
});
Gate::define('worker', function ($user) {
return $user->StatusReg == 'worker';
});
Gate::define('customer', function ($user) {
return $user->StatusReg == 'customer';
});
And then you can use it in your application like the following:
if (Gate::allows('worker')) {
//...
}
if (Gate::denies('customer')) {
//...
}
There are plenty more usage examples in the docs:
https://laravel.com/docs/5.6/authorization
I am using 'jrean' package in Laravel for verifying emails of registered users.
https://packagist.org/packages/jrean/laravel-user-verification
The problem I am facing currently is even if the user is registered how can I restrict his access until the email is not verified. I have followed all the steps given in the package tutorial for implementing registration. But they don't have any steps listed for restricting login access. Any ideas?
You can overwrite your login method. In L5.2 and asumming you have a verified field in your users table which is boolean you can do something like:
In your app/Http/Controllers/Auth/AuthController.php add something like:
use Illuminate\Foundation\Auth\AuthenticatesAndRegistersUsers;
use Illuminate\Foundation\Auth\ThrottlesLogins;
use Illuminate\Support\Facades\Auth;
/**
* Handle a login request to the application.
*
* #param \Illuminate\Http\Request $request
* #return \Illuminate\Http\Response
*/
public function login(Request $request)
{
$this->validateLogin($request);
$throttles = $this->isUsingThrottlesLoginsTrait();
if ($throttles && $lockedOut = $this->hasTooManyLoginAttempts($request)) {
$this->fireLockoutEvent($request);
return $this->sendLockoutResponse($request);
}
$credentials = $this->getCredentials($request);
if (Auth::guard($this->getGuard())->attempt($credentials, $request->has('remember'))) {
if (Auth::user()->verified == true) { // This is the most important part for you
return $this->handleUserWasAuthenticated($request, $throttles);
} else {
Auth::logout();
return $this->sendFailedLoginResponse($request, "Some message here");
}
}
if ($throttles && !$lockedOut) {
$this->incrementLoginAttempts($request);
}
return $this->sendFailedLoginResponse($request);
}
You also need to add the verified field in your User eloquent model in order to use it in your modified login method.
Hope it helps!
You can create simple middleware and check if email is verified there. For example, if verified is boolean in users table, you can do this:
public function handle($request, Closure $next)
{
return auth()->user() && auth()->user()->verified
? $next($request); // Will pass user.
: redirect('/'); // Will redirect user to the main page if email is not verified.
}
}
Do not forget to register middleware and apply it to route(s) you want to protect.
Apply verified middleware to the URL and it will prevent visiting the URL until user verifies their email. Route::get('/users', 'UserController#index')->name('users')->middleware('verified');
Use this:
public function __construct() {
$user = Auth::guard('api')->user();
if(!$user->hasVerifiedEmail()) {
abort($this->respondUnauthorized(trans('response.email_not_verified')));
}
}
hasVerifiedEmail() Determine if the user has verified their email address.
It will check for all routes/methods in your controller
public function handle($request, Closure $next, $guard = null)
{
if (Auth::guard($guard)->check()) {
return redirect('/');
}
return $next($request);
}
public function handle(Request $request, Closure $next)
{
if (\App\Models\User::where('email', $request->input('email'))->first()->email_verified_at != null) {
return $next($request);
} else {
return redirect('/login')->with('email_not_verified', 'Email not verified, Please check your email to validate it');
}
}