I liked Matrix Admin panel, so i started implementing it. I didnt like the option of having admin in User model (boolean check isAdmin), so i created a separate model called Admin. I set up all the routes, and it worked in my test admin page with the following routes:
web.php
Route::get('/admin/login', 'Auth\AdminLoginController#showLoginForm')-
>name('admin.login');
Route::post('/admin/login', 'Auth\AdminLoginController#login')-
>name('admin.login.submit');
Route::get('/admin', 'AdminController#index')->name('admin.admin');
This is my AdminLoginController:
public function showLoginForm()
{
return view('admin/admin-login');
}
protected function guard(){
return Auth::guard('admin');
}
use AuthenticatesUsers;
protected $redirectTo = '/admin/login';
public function __construct()
{
$this->middleware('guest:admin')->except('logout');
}
And my AdminController:
public function __construct()
{
$this->middleware('auth:admin');
}
public function index()
{
return view('admin.admin');
}
I call routes in the view like this:
href="{{ route('admin.login') }}"
For some reason, it doesn't log me out and get me to the login page, instead it just refreshes the page, hence returns me to the /admin page with the admin logged in. What am i missing here? Thanks for all replies.
In the constructor for the AdminLoginController, you have set the middleware to be 'guest:admin'.
This uses the guest middleware that is defined in /app/Http/Middleware/RedirectIfAuthenticated.php by default, or configured in /app/Http/Kernel.php
The $guard string passed for it to use is 'admin'.
I'm guessing that you provide an implementation for this admin guard.
Supposing that you're logged in as an admin, navigating to route('admin.login')
will redirect your request to '/home' in the default implementation;
there are likely chances that there exists a custom redirection to /admin in your implementation.
If you like to logout of the session, you can register a route for the logout method provided in Illuminate\Foundation\Auth\AuthenticatesUsers trait.
Route::get('/admin/logout', 'AdminController#logout')->name('admin.logout');
Since the AuthenticatesUsers::logout redirects to / by default, I'm guessing you need to override this behavior.
You can do exactly that by providing a custom implementation for AuthenticatesUsers::loggedOut in your controller.
protected function loggedOut(Request $request)
{
return redirect('/admin');
}
Finally, provide this route for the href in your link {{ route('admin.logout') }}
It's all about session,
\Auth::logout();
$request->session()->invalidate();
Related
I am working in Laravel auth application and when my user is log out I want to redirect it to custom static page and from there I want to redirect to login page again by clicking button on that page.
For example when user is trying to access some particular route, and he is unauthorized then I want to redirect with satatic.blade.php and from there I want to redirect it to log in page, How can I make it happen?
As you didn't mention which Laravel version you are using and which scaffolding you are using, I am assuming you are using Laravel 5.5/6 with LaravelUI/default auth scaffolding.
You should have App\\Http\\Controllers\\Auth namespace where you kept all auth related controller.
You should have one LoginController.php which contains all default login behavior inside AuthenticatesUsers trait. We should override the login method inside our controller.
Copy this code to your LoginController class to do so.
public function login(Request $request)
{
$this->validateLogin($request);
if (method_exists($this, 'hasTooManyLoginAttempts') &&
$this->hasTooManyLoginAttempts($request)) {
$this->fireLockoutEvent($request);
return $this->sendLockoutResponse($request);
}
// Here is our custom logic check occurs before login
if ($this->userIsnotAuthorized()) { // All your logic checks are inside 'userIsnotAuthorized()' method. Use any function or static check here
return redirect()->to('/static/page'); // Also can use route name / url
}
if ($this->attemptLogin($request)) {
return $this->sendLoginResponse($request);
}
$this->incrementLoginAttempts($request);
return $this->sendFailedLoginResponse($request);
}
EDIT #1
If you want to have the same check for all protected routes, you should generate a middleware with php artisan make:middleware CheckResourceAccessMiddleware and use the same in your route.
In CheckResourceAccessMiddleware's handle method
// Here is our custom logic check occurs before login
if ($this->userIsnotAuthorized()) { // All your logic checks are inside 'userIsnotAuthorized()' method. Use any function or static check here
return redirect()->to('/static/page'); // redirect to static page which indicates unauthorized user note
}
return $next($request); // proceed to your page as user is authorized
to register the middleware edit your app/Http/Kernel.php and add this line to $routeMiddleware array
protected $routeMiddleware = [
...
'resource_access' => \App\Http\Middleware\CheckResourceAccessMiddleware::class,
];
After this step., you can use the middleware in any routes you want to protect
Route::get('/protected', [Controller::class, 'method'])->middleware('resource_access');
OR
// Middleware will be applied to all routes inside it
Route::middleware('resource_access')->group(function () {
Route::get('/protected', [Controller::class, 'method']);
// all other protected routes will be here
});
I found different approaches for this problem, Later I Found the best solution, as mention below,
In App\Middlewear\Authenticate.php, I have to change from return route('login');
to return route('my_custom_page_route');
From my custom page I can redirect it to auth login page easily.
Thank you everyone who suggest the best solutions.
I have a Laravel routing file (web.php) like so:
Route::group(['middleware' => ['auth']], function () {
Route::get('/', function () {
return 'Hello World';
});
});
Route::get('/', 'Auth\LoginController#showLoginForm')->name('login');
In my application the unauthenticated homepage must go to the login screen. When authenticated, the homepage changes. However, if I run this code and login - I get an infinite redirect because the LoginController has this line:
protected $redirectTo = '/';
So basically, even thought Laravel should read the routes file top to bottom, it seems this isn't applying in my case (maybe because of the ::group()) or I am doing something wrong.
How can I accomplish a homepage that goes to the login form while also redirecting back to the same url (/) for authenticated users for a different authenticated view (and no redirect loop).
Thanks!
I would handle this inside a guest middleware that checks for an authenticated user. For this case you'll want an authenticated guard check first:
use Illuminate\Contracts\Auth\Guard;
public function __construct(Guard $auth)
{
$this->auth = $auth;
}
public function handle($request, Closure $next)
{
if ($this->auth->check()) {
return redirect('/home');
}
return $next($request);
}
Apply the guest middleware to the login endpoint:
Route::get('/', 'Auth\LoginController#showLoginForm')
->middleware('guest')
->name('login');
Note: Only apply the guest middleware to guest routes, otherwise you run the risk of redirect loops.
Why not handle this in your view?
You can simply remove one of the route declaration from your web.php.
Then go ahead with conditional rendering.
#auth
Show Home page
#endauth
#guest
Show Login
#endguest
I guess middleware does not prevent request from hitting the routes,
It rather prevents request from going through.
You can't use middleenter code hereware to decide with route to hit, thereby the loop.
When you're thinking in terms of bottom down processing, laravel has already registered every declared routes.
I'm struggling to get the login/register pages to redirect the user if already logged in.
in routes.php
Route::group(array('before' => 'auth'), function()
{
Route::get('hud', 'HomeController#index')->name('hud');
Route::get('search', 'HomeController#search')->name('search');
Route::get('profile', 'UsersController#index')->name('profile');
Route::get('clients', 'ClientsController#index')->name('clients');
Route::delete('clients/{id}', 'ClientsController#destroy');
Route::resource('projects', 'ProjectsController', array('only' => array('show')));
});
I've tried no_auth and it just breaks. Am I missing something?
You should set the redirect path for when a given visitor is authenticated user.
You can do so in: App\Http\Middleware\RedirectIfAuthenticated
Example:
public function handle($request, Closure $next)
{
if ($this->auth->check()) {
return redirect('/dashboard');
}
return $next($request);
}
Stackoverflow: laravel redirect if logged in
You want to redirect already registered user to Homepage whenever they try to hit /login.
Here's how laravel tries to achieve that.
Firstly this is achieved through App\Http\Middleware\RedirectIfAuthenticated.
However a key to this middleware is registered to guest in this file app\Http\Kernel.php under array protected $routeMiddleware.
Then in your login controller presumably at app\Http\Controllers\Auth\LoginController.php
In the construct method, We have something like this:
class LoginController extends Controller
{
use AuthenticatesUsers;
protected $redirectTo = '/';
public function __construct()
{
$this->middleware('guest')->except('logout');
}
}
I have searched all over the place, none of the answers was to my needs.
I have a Laravel app, with various pages that require the user to be logged in.
The normal redirect in Laravel after login is to the home page.
How can I make a redirect to the original page that requested the login?
For example:
A user tries to go to example.com/page/1 that is for authenticated users only. He is redirected to the login page, submit the form and then redirects to the home page. How can I redirect him back to example.com/page/1 or whatever page that he came from?
You can use intended method for this purpose, From the docs:
The intended method on the redirector will redirect the user to the
URL they were attempting to access before being intercepted by the
authentication middleware. A fallback URI may be given to this method
in case the intended destination is not available.
In your Login Controller add the below code:
public function authenticate(Request $request)
{
$credentials = $request->only('email', 'password');
if (Auth::attempt($credentials)) {
// Authentication passed...
return redirect()->intended('dashboard');
}
}
You could potentially hook in to Laravel's intended() method. Usually, this would be a guarded route that a user tried to access before they were redirected to the login page but you can manually set it to what ever you want it to be.
In your LoginController add the following:
public function showLoginForm()
{
if (!session()->has('url.intended')) {
redirect()->setIntendedUrl(session()->previousUrl());
}
return view('auth.login');
}
This will check to see if the intended url is set, if it isn't it will set it to the previous url.
in your LoginController :
protected function authenticated(Request $request, $user) {
return redirect()->back();
}
I need to redirect an admin user to the dashboard after he logs in. To achieve this, I've overriden the redirectPath() method that is located in RedirectUsers trait. Here is the code:
public function redirectPath()
{
if (property_exists($this, 'redirectPath')) {
return $this->redirectPath;
}
// MODIFICATIONS ------------------------------
if(request()->user()->hasRole('admin')){
return '/dashboard';
}
// ENDMODIFICATIONS ---------------------------
return property_exists($this, 'redirectTo') ? $this->redirectTo : '/home';
}
The problem
Dashboard redirection works only in some cases:
At first login, the admin is redirected to the home page.
At subsequent logins, the admin is redirected to the dashboard.
But if php artisan cache:clear command is run, admin gets redirected to the home page again.
Why is this happening and how do I implement this functionality correctly?
Instead of overriding redirectPath(), you can create authenticated method in your AuthController.php, it will be called if exists after user successfully authenticated:
class AuthController extends Controller
use AuthenticatesAndRegistersUsers, ThrottlesLogins;
...
public function authenticated()
{
if(Auth::guard($this->getGuard())->user()->hasRole('admin')){
return redirect('/dashboard');
}
return redirect()->intended($this->redirectPath());
}
}
How about middleware.
Make a middleware named RedirectIfAdmin.
Then place it in to the Homecontroller __construct.
I think this maybe more like laravel thinking.
NEVER CHANGE ANYTHING ANY FILES IN VENDOR FOLDER!
It will cause issues when you are trying to update the packages as it will overwrite everything that is old! Also, by default, git will not track any files inside vendor folder
Here is the alternative and how it supposed to work:
Add $redirectTo attribute in your AuthController.php
class AuthController extends Controller {
protected $redirectTo = '/user/dashboard';
}
Then, in your controller, you can do something like this:
if(Auth::guard($this->getGuard())->user()->hasRole('admin')){
$this->redirectTo = '/dashboard'
}
What will happen:
public function redirectPath()
{
if (property_exists($this, 'redirectPath')) {
return $this->redirectPath;
}
return property_exists($this, 'redirectTo') ? $this->redirectTo : '/home';
}
Whenever any method calling redirectPath function, it will check if the attribute of redirectPath is exist or not. If exist, use the provided url instead. If not, use the default which is '/home`