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');
}
Related
I have a view (resources/view/front/auth/profile.blade.php) and my route in file web.php is:
Route::get('/profile/{user}','UserController#edit')
->name('profile')
->middleware('profilecheck');
My problem is that when a user logs in and gets redirected to their own profile page (http://exmaple.com/profile/2), he/she can change the URL to http://exmaple.com/profile/3 and see other users' profile.
I want to use a middleware to check authenticated users id with URL parameter {user}. The $user->id will passed to the {user}, but I have no idea how.
Middleware UserProfile.php:
<?php
namespace App\Http\Middleware;
use App\User;
use Closure;
class UserProfile
{
/**
* Handle an incoming request.
*
* #param \Illuminate\Http\Request $request
* #param \Closure $next
* #return mixed
*/
public function handle($request, Closure $next)
{
// $request->user()->id
// Auth::user()->id
return $next($request);
}
}
You can protect the route simply by removing the user id from the URL, but getting it through the authentication session instead.
So, your route signature should goes from:
Route::get('/profile/{user}', 'UserController#edit')->name('profile');
To this:
Route::get('/profile', 'UserController#edit')->name('profile');
So, in your controller, instead of getting the user id from the request:
public function edit(Request $request)
{
$user = User::findOrFail($request->id);
// ...
}
You could get the logged-in User through the Auth facade:
use Illuminate\Support\Facades\Auth;
public function edit(Request $request)
{
$user = Auth::user();
// ...
}
or just the auth() helper:
public function edit(Request $request)
{
$user = auth()->user();
// ...
}
This way, you are masking the URL to avoid a malicious user of doing things that he/she shouldn't.
You need to do something like this.
Your route
Route::get('/profile', [
'uses' => 'UserController#profile',
'middleware' => 'profilecheck'
]);
Your middleware
class CheckUserMiddleware
{
public function handle($request, Closure $next)
{
if(!auth()->user()) {
return redirect()->route('login');
}
return $next($request);
}
}
// Controller
public function index()
{
if (Auth::check() && Auth::user()->role->id == 2) {
return view('author.setting.settings');
} else {
Toastr::info('you are not authorized to access', 'Info');
return redirect()->route('login');
}
}
// Route
Route::group(['as'=>'user.','prefix'=>'user','namespace'=>'Author','middleware'=>['auth','user']], function (){
Route::get('/setting','SettingsController#index')->name('settings.settings');
});
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 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");
}
}
I have an authentication middle ware to check the validity of the passed api key. I fetch user id from the database store it to the request array so that the requesting page will get the userid.
public function handle($request, Closure $next) {
$key = $request->get('key');
$user = User::where('token', '=' ,$key)->first();
if($user != null){
$request->request->add(['middlewareUserID' => $user->id]);
return $next($request);
}
else {
return response(401);
}
}
Is it a good practice?
I would say this is not necessary in such case.
I would use code similar to this:
use Illuminate\Contracts\Auth\Guard;
class YourMiddleware
{
protected $guard;
public function __construct(Guard $guard)
{
$this->guard = $guard;
}
public function handle($request, Closure $next) {
$key = $request->get('key');
$user = User::where('token', '=' ,$key)->first();
if(!$user){
return response(401);
}
$this->guard->setUser($user);
return $next($request);
}
}
so when there is user for given token you can authenticate user in line $this->guard->setUser($user); and when the token is invalid you return return response(401);
I don't see any need to set this user id to request as you showed.
Type error: Argument 3 passed to App\Http\Middleware\UserAuthMiddleware::handle() must implement interface App\Contracts\UserAuth, none given, called in C:\wamp64\www\laravel\vendor\laravel\framework\src\Illuminate\Pipeline\Pipeline.php on line 148
I'm getting this error from inside a middleware, but when I'm use the given contract in my controllers, it works just fine. Does anyone have a clue what is happening?
Middleware file
namespace App\Http\Middleware;
use Closure;
use App\Contracts\UserAuth;
class UserAuthMiddleware
{
/**
* Handle an incoming request.
*
* #param \Illuminate\Http\Request $request
* #param \Closure $next
* #return mixed
*/
public function handle($request, Closure $next, UserAuth $user)
{
return $next($request);
}
}
UserAuth service file
<?php
namespace App\Services;
use App\UsersModel;
class UserAuth implements \App\Contracts\UserAuth
{
public $username;
public $password;
public $perm_level = "admin";
public $guest = true;
public function load()
{
if (session()->has("user"))
{
$user = UserModel::where([
"username" => session("user"),
"password" => session("password")
])->first();
$this->username = $user->username;
$this->password = $user->password;
$this->guest = false;
}
}
public function isLogged()
{
return $this->guest;
}
}
AppServiceProvider register
public function register()
{
$this->app->singleton(\App\Contracts\UserAuth::class, \App\Services\UserAuth::class);
}
Routes
//REGISTRATION ROUTES
Route::get("/register", "User#register")->middleware("user_auth");
Route::post("/register", "User#save_user")->middleware("user_auth");
User controller with working contract
<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
use App\UsersModel;
use App\Contracts\UserAuth;
class User extends Controller
{
public function register(Request $request, UserAuth $user)
{
return view("registration.form", ["request" => $request]);
}
public function login(Request $request)
{
$user = UsersModel::where([
"username" => $request->username,
"password" => $request->password
])->first();
if ($user)
{
session(["user" => $user->username, "password" => $user->password]);
return back();
}
else return back()->with("login_attempt", "failed");
}
public function logout()
{
session()->forget("user", "password");
return back();
}
public function save_user(Request $request)
{
$errors = [];
//Data validation
$input = $request->all();
if ( in_array(null, $input) )
$errors["empty_fields"] = true;
if ( !preg_match("/[A-Za-z0-9 ]{3,16}/", $input["username"]) )
$errors["invalid_username"] = true;
if ( $input["password"] != $input["password_confirm"] )
$errors["unmatching_passwords"] = true;
if ( !preg_match("/[A-Za-z0-9\-\.]{3,16}#[A-Za-z0-9](\.[a-z0-9]){1,2}/", $input["email"]) )
$errors["invalid_email"] = true;
if ( UsersModel::where("username", $input["username"])->first() )
$errors["username_taken"] = true;
if (count($errors) > 0) return view("registration.form", ["err" => $errors, "request" => $request]);
else return view("registration.save", ["request" => $request]);
}
}
You are incorrectly trying to pass an ad-hoc paramter to the handle function in your middleware parameter.
When you define this:
public function handle($request, Closure $next, UserAuth $user)
That means that the middleware is expecting a parameter to be passed in there, it will not come from DI Container, hence the $user variable is null, failing to pass the type-hint constraint.
The parameters that are allowed here are only for "roles", you cannot pass something random and expect the DI container to resolve it.
I would suggest you try something like this instead:
public function handle($request, Closure $next)
{
if($request->user()->isLogged()) {
return $next($request);
} else {
return redirect('login'); // or whatever route
}
}
For this to work, you would need to define the isLogged function as part of a Trait, that you would add to you App\User model.
Please see:
https://laracasts.com/discuss/channels/laravel/pass-variable-from-route-to-middleware
https://laravel.com/docs/5.4/middleware#middleware-parameters