Laravel Custom Middleware - laravel

I am trying to achieve this using middleware
web.php
Route::get('/test', 'TestController#index')->middleware('TestLogin');
redirect to /test if session is found
Route::get('/test1', 'TestController#index1')->middleware('TestLogin');
redirect to test1 if session is set
Middleware -TestLogin
public function handle($request, Closure $next)`
{
if($request->session()->get('Username'))
{
return redirect()->route(\);
// what to write here to redirect to the path its being called from
}
return redirect()->route('login');
}
don't want to use default auth middleware

Your middleware is suppose to check the login (session), if it is not found then redirect to login page otherwise it should pass the request. Something like this:
public function handle($request, Closure $next)
{
// No login session, redirect
if(!$request->session()->get('Username'))
{
return redirect()->route('login');
}
// Pass the request down the rest of pipeline
return $next($request);
}
You should consider to use built in authentication system in Laravel itself, it will save you lots of code and you can be sure the auth is handled correctly in security point of view.

Related

Laravel - change route in middleware

Let's say I have this kind of URLs :
example.com/en/
example.com/en/login
example.com/fr/login
I would like to use a middleware to set the language and then return the route to be handled without the language part. So the router would get / or /login, without any language stuff.
public function handle(Request $request, Closure $next) {
app()->setLocale($request->segment(1));
// $request->server->set('REQUEST_URI', substr($_SERVER['REQUEST_URI'], 4));// not working
return $next($request);
}
I would suggest to store the language in session and use a middleware to setLocale.
Working example
SetLocale.php middleware
public function handle($request, Closure $next)
{
if (Session::has('language'))
{
App::setLocale(strtolower(Session::get('language')));
}
return $next($request);
}
Controller function to set language to session
public function setLanguage(string $language)
{
if (Session::has('language'))
{
Session::forget('language');
}
Session::put('language', $language);
return redirect()->back();
}
So now on everything that happens on the website, the middleware will check the language and set it to what's in session.
Also don't forget to specify the middleware in $middlewareGroups in app\Http\Kernel.php
You can create a form anywhere on website for the user to choose his language preference with a route to the controller function.

laravel: how to stay login until a condition becomes false?

I have a field (can_login) in my users table.
normally,users can login. and logout with this code:
Auth::logout();
I want, when each time a logged-in user refresh a page,
laravel check can_login in user table.
if can_login is false, then auto logout.
I try this in RouteServiceProvider
public function boot()
{
parent::boot();
if(auth()->user()->can_login){
return route('logout');
}
}
but auth()->user() is always empty.
You can use a middleware or add a check to your existing authentication middleware.
On each request it passes through a middleware to check if user is authenticated and after that auth()->user() will not be empty.
Simplest solution would be to create a middleware in app/Http/Middlewares/CheckUserCanLoginMiddleware.php
class CheckUserCanLoginMiddleware
{
public function handle(Request $request, Closure $next)
) {
if ($request->user()->can_login ?? false) {
Auth::logout();
return $this->sendUnauthorizedResponse();
}
return $next($request);
}
}
And then register it as a routeMiddleware` in your bootstrap/app.php file.
The last thing you need is to use it to our routes middlewares after authentication middleware.

Can't access user model in middleware

I created a custom middleware for checking if request is submitted by user who owns the resource or owned by admin.
Route::middleware(['web', 'selforadmin'])->group(function () {
Route::post('users/update-account/{id}', 'UsersController#UpdateAccount');
Route::post('users/update-email/{id}', 'UsersController#UpdateEmail');
Route::post('users/update-password/{id}', 'UsersController#UpdatePassword');
});
and then the middleware handler:
public function handle($request, Closure $next)
{
print_r($request->all());
print_r($request->user());
dd();
return $next($request);
}
But I don't know why user model is not accessible here. I read that request needs to pass from web middleware first so I did but still can't access this middleware.
It gives null on $request->user() or Auth::user()
I am using Laravel 5.4
EDIT:
Middleware is being called as I see other inputs. Only Auth is empty. And User is logged.
You can't access using models directly in middleware. You need to define a terminate method in your middleware to perform some processing after response has been sent to browser.
public function terminate($request, $response)
{
// Your code ...
}
If user is not logged in it will always return null.
There are two solution for this.
First is, check if $request->user() is not null.
public function handle($request, Closure $next)
{
if($request->user())
{
// do your stuff
}
else
{
// do otherwise
}
return $next($request);
}
Second is, add auth middleware before your middleware to assure that only logged in users are allowed.
Route::middleware(['web', 'auth', 'selforadmin'])->group(function () {
// .....
}

How can I change the redirect path after login and logout in Laravel 5.3?

I have changed the protected $redirectTo = '/tasks'; in both the LoginController and RegisterController.
Also, I have changed the redirect path in the middleware RedirectIfAuthenticated as follows:
public function handle($request, Closure $next, $guard = null)
{
if (Auth::guard($guard)->check()) {
return redirect('/tasks');
}
return $next($request);
}
Even though I have done these changes, nothing works, and the pages are redirected to the /login path.
That's because $redirectTo will take effect after you have logged in. First of all you need to login. That's why it's sending you to /login path. So if you want to change where it redirects after Login or Registration, you change those $redirectTo properties. If you don't want a user to login at all, you should remove the auth middleware for that route.
EDIT:
So what you have missed is that laravel redirects you back to the intended page and if there is none it will redirect to $redirectTo. So if you try to go to homepage and that needs authenticated user, after login it redirects back to the homepage and not /tasks because that's where you were trying to go. If you want to always redirect to that path and not to intended path you can do something as below.
protected function sendLoginResponse(Request $request)
{
$request->session()->regenerate();
$this->clearLoginAttempts($request);
return redirect()->to($this->redirectTo);
}
Add this code to your LoginController and you will always be redirected to $redirectTo.
After seeing your code, I got that your IF statement is not returning true. You have to first see, what is it returning. Also, redirect to your desired location without any condition just to test the code.
Also, I am using this code for redirection after login in my application.
public function handle($request, Closure $next)
{
if ($this->auth->check()) {
return redirect('/home');
}
return $next($request);
}

Redirect if authenticated in Laravel 5.3

I'm using the Auth scaffold in Laravel 5.3 and I've changed the routes for the auth. So instead of /login and /register I use /signin and /signup.
In Laravel 5.2 we had this by default in the auth middleware,
public function handle($request, Closure $next, $guard = null)
{
if (Auth::guard($guard)->guest()) {
if ($request->ajax() || $request->wantsJson()) {
return response('Unauthorized.', 401);
}
return redirect()->guest('login');
}
return $next($request);
}
This would redirect to the login route if the user wasn't logged in. In Laravel 5.3 we have this,
public function handle($request, Closure $next, $guard = null)
{
if (Auth::guard($guard)->check()) {
return redirect('/');
}
return $next($request);
}
This redirects an already logged in user to the default route /. So they switched it around in 5.3. Instead of defining where guest go, we define were logged in users go.
My question is, how would I natively to Laravel 5.3 change were guests go?
Because at the moment, people who try to access sites protected by the middleware automatically end up at a /login route. I would like to change this to /signin but I can't find anywhere to customize this behaviour.
Any ideas?
how would I "natively" to Laravel 5.3 change were guests go?
Looks like there's a new unauthenticated() method in app/Exceptions/Handler.php which handles unauthenticated users and redirects to login.
As this is part of your app, no reason you couldn't customize it to redirect elsewhere.
You can try this in the app.blade.php with JS:
#if (Auth::guest())
<script type="text/javascript"> window.location = "{{url('/login')}}"; </script>
#endif

Resources