Laravel 5 Auth - Change Login Route - laravel-5

I'm trying to redirect my user to 'homepage' after successful login.
I've been able to redirect after logout by adding the following to AuthController:
protected $redirectAfterLogout = 'homepage';
However, adding the following to AuthController does not work after login. It directs me to 'home."
protected $redirectPath = 'homepage';
I then changed the default redirect in the handle() function in RedirectIfAuthenticated to:
return redirect('homepage');
Not only does that not work, it gives me the following error:
This webpage has a redirect loop
ERR_TOO_MANY_REDIRECTS
Does anyone know how I can achieve redirecting to 'homepage' after login?
Edit - Adding Routes:
Route::get('/', function () {
return view('welcome');
});
Route::get('home', 'HomepageController#getIndex');
Route::get('homepage', 'HomepageController#getIndex');
Thanks for any guidance!

Dude the attribute should be named as $redirectTo:
$redirectTo = "homepage";
now if you got more than one rule like admin and user, stored within your user model as type field, you may override the value of this attribute within postLogin() function, override the function first then do your changes. i.e:
// AuthController.php
/**
* #param Request $request
* #return $this|\Illuminate\Http\RedirectResponse
*/
public function postLogin(Request $request)
{
$this->validate($request, [
'email' => 'required|email', 'password' => 'required',
]);
$credentials = $request->only('email', 'password');
if ($this->auth->attempt($credentials, $request->has('remember')))
{
$user=User::find($this->auth->user()->id);
if($user->type == "ADMIN")
$this->redirectTo = "/dashboard";
return redirect()->intended($this->redirectPath());
}
return redirect($this->loginPath())
->withInput($request->only('email', 'remember'))
->withErrors([
'email' => $this->getFailedLoginMessage(),
]);
}

I got around this by simply modifying the existing Route::get('/') to the following:
Route::get('/', 'HomepageController#getIndex');
I really didn't need the Welcome View any longer, so this solution made the most sense.
Also, after modifying this Route, I was able to remove my previous 'home' and 'homepage' Routes.

Related

Laravel multi authetification with different users tables

I'm trying to build a multiple authentification in laravel with different tables (2 tables) for admin and user. The problème is that the registration and login forms work only with default auth login/register.
I've tried some examples form web tutorials but it didn't work.
HomeController.php:
public function __construct() {
$this->middleware('auth');
}
public function index() {
return view('home');
}
I have added createAdmin function in "Auth/RegisterController.php":
protected function createAdmin(array $data)
{
$this->validator($data->all())->validate();
$admin = Admin::create([
'name' => $data['name'],
'email' => $data['email'],
'password' => Hash::make($data['password']),
]);
return redirect()->intended('login/admin');
}
I have changed email validation rules to:
'email' => ['required', 'string', 'email', 'max:255', 'unique:users'|'unique:admins']
And the route (web.php) is:
Route::post('/register/admin', 'Auth\RegisterController#createAdmin');
When I fill admin register credentials and click register button I get this message:
Symfony\Component\Debug\Exception\FatalThrowableError Too few arguments to function App\Http\Controllers\Auth\RegisterController::createAdmin(), 0 passed and exactly 1 expected
The error is coming from the array $data parameter in your createAdmin() controller method.
Usually, you want to use one of two types of parameters in your controller methods: route parameters or injected dependencies. The $data parameter isn't matching either of those, so Laravel doesn't know to provide it.
If you'd like to access the request (POST) data in the controller, you can either ask for an instance of Illuminate\Http\Request as a parameter:
// Import it at the top of your PHP file
use Illuminate\Http\Request;
// Then your updated method:
public function createAdmin(Request $request)
{
$data = $request->all();
// ...
}
Or, use the request() helper directly:
public function createAdmin()
{
$data = request()->all();
// ...
}

Laravel 5.4 redirect to specific page if user is not authenticated using middleware

I want to redirect user, if not authenticated, to my index page (which is the login page)
Can't seem to make it work and i really got confused with the routing.
HomeController
class HomeController extends Controller
{
/**
* Show the application dashboard.
*
* #return \Illuminate\Http\Response
*/
public function index()
{
return redirect()->guest('/');
}
}
Routing
// Index
Route::get('/', [
'as' => 'index',
'uses' => 'UserController#index'
]);
UserController
The routing as you see redirects to a User Controller at index function, which is the below :
*has __construct() so it uses the middleware 'auth'.
public function __construct()
{
$this->middleware('auth');
}
public function index(){
// If user is logged
if(Auth::check()) {
// If user has NOT submitted information form redirect there, otherwise to categories
if(!Auth::user()->submitted_information)
return redirect()->route('information');
else
return redirect()->route('categories');
}
else
return view('index', ['body_class' => 'template-home']);
}
Handler.php
And the unauthenticated function inside middleware of auth (Exceptions/Handler.php)
protected function unauthenticated($request, AuthenticationException $exception)
{
if ($request->expectsJson()) {
return response()->json(['error' => 'Unauthenticated.'], 401);
}
return redirect()->route('index');
}
The error i get right now is the below :
InvalidArgumentException in UrlGenerator.php line 304:
Route [index] not defined.
This error happens because of the line of
return redirect()->route('index'); in the above unauthenticated function.
What am i missing here? If you need any more information please feel free to ask.
EDIT : Until now, if i remove from UserController the __construct() method, and insert in web.php to all the routes what middleware to use, it works.
For example
Route::get('/categories', [
'as' => 'categories',
'uses' => 'UserController#showCategories'
])->middleware('auth');
But i am trying to find, without specifying there what middleware to use, to use it automatically.
Build your route like below code:
Route::group(['middleware' => ['auth']], function() {
// uses 'auth' middleware
Route::resource('blog','BlogController');
});
Route::get('/mypage', 'HomeController#mypage');
Open your middleware class named RedirectIfAuthenticated and then in handle fucntion
you write below code:
if (!Auth::check()) {
return redirect('/mypage'); // redirect to your specific page which is public for all
}
Hope it will work for you.
Your route should be like
// Index
Route::get('/','UserController#index')->name('index);
see here for more about routing.
Try
Route::get('/','UserController#index',['middleware'=>'auth'])->name('index);

How to check user status while login in Laravel 5?

I have used Laravel Authentication (Quickstart). But I need to check the status of the user (approved/pending). If not approved, then an error will be shown in the login page. I need to know in which file I have to make the change and what is the change. Currently I am working on Laravel 5.3.
You can create a Laravel Middleware check the link for additional info
php artisan make:middleware CheckStatus
modify your middleware to get
<?php
namespace App\Http\Middleware;
use Closure;
use Illuminate\Support\Facades\Auth;
class CheckStatus
{
/**
* Handle an incoming request.
*
* #param \Illuminate\Http\Request $request
* #param \Closure $next
* #return mixed
*/
public function handle($request, Closure $next)
{
$response = $next($request);
//If the status is not approved redirect to login
if(Auth::check() && Auth::user()->status_field != 'approved'){
Auth::logout();
return redirect('/login')->with('erro_login', 'Your error text');
}
return $response;
}
}
then add your middleware to your Kernel.php
'checkstatus' => \App\Http\Middleware\CheckStatus::class,
and finally add the middleware to your route
Route::post('/login', [
'uses' => 'Auth\AuthController#login',
'middleware' => 'checkstatus',
]);
I hope it helps
I found a simple solution for this. Artisan create App\Http\Controllers\Auth\LoginController, in this default controller just add this code if you have some conditions to login, for example I have a field state, you posibbly have status, email_status or other.
// Custom code for Auth process
protected function credentials( Request $request )
{
$credentials = $request->only($this->username(), 'password');
$credentials['state'] = 1;
return $credentials;
}
upper answer saves me
if (Auth::attempt(['email'=>$input['email'],'password'=>$input['password'], 'user_status'=>1 ]))
this will check the status
Just Add following method in my LoginController works like charm
protected function authenticated(Request $request, $user)
{
if ($user->yourFirldName != "Active") {
Auth::logout();
return redirect('/login')->with('error', 'Looks Like Your status is InActive');
}
}
I don't agree with upper answer, which will lead to your application performance is very low, and also don't recommend to modify the Laravel's source code.
So you can rewrite getCredentials function to your app\Http\Controllers\Auth\AuthController.php file like this:
<?php
//app\Http\Controllers\Auth\AuthController.php
namespace App\Http\Controllers\Auth;
use App\Http\Controllers\Controller;
use Illuminate\Foundation\Auth\ThrottlesLogins;
use Illuminate\Foundation\Auth\AuthenticatesAndRegistersUsers;
use Illuminate\Http\Request;
class AuthController extends Controller
{
use AuthenticatesAndRegistersUsers, ThrottlesLogins;
//you need add this function
protected function getCredentials(Request $request)
{
$data = $request->only($this->loginUsername(), 'password');
$data['is_approved'] = 1;
return $data;
}
}
then you can use Laravel Authentication (Quickstart) directly.
Hope this will help.
The pinned answer is the best approach.
Just a note: if you are using Laravel 5.8+ you need use:
//Default Auth routes
Auth::routes();
//Override and add middleware
Route::post('/login', [
'uses' => 'Auth\LoginController#login',
'middleware' => 'checkstatus',
]);
Follow the steps...
First add a column in your user table (suppose is_approved)
In App/Http/Controllers/Auth/LoginController file
public function authenticate()
{
if (Auth::attempt(['email' => $email, 'password' => $password, 'is_approved'=>1])) {
// Authentication passed...
return redirect()->intended('dashboard');
}
}
Hope this will help
Auth/LoginController
Though it is a long time from the question created date. You can go this way.
Go to Auth/LoginController and add this line.
protected function credentials(Request $request)
{
return [
'email' => $request->email,
'password' => $request->password,
'status' => 1,
];
}
For this to work you have to have a column named 'status' in users table. 1 is for active and 0/2 is for inactive user.
Hope this will work for you.
public function login(Request $request){
if ($request->isMethod('post')) {
$data= $request->all();
$roles=[
'email' => 'required|email|max:255',
'password' => 'required',
];
$customessage=[
'email.required' =>'Email is required',
'email.email' => 'Email is not vaild',
'password.required' => 'Password is required',
];
$this->validate($request,$roles,$customessage);
if(Auth::guard('admin')->attempt(['email'=>$data['email'],'password'=>$data['password'],'status'=>1])) {
return redirect('admin/dashboard');
} else {
Session::flash('error_message','You are not Active by Admin');
return redirect()->back();
}
}
return view('admin.admin_login');
}

Laravel login redirected you too many times

I have been struggling with this from quiet a time now, what i am trying is to redirect all the url's hit by non-logged in users to login page and it gives me this error, which I am sure is because it is creating a loop on /login URL. authentication is checking for authorized user in login page also. however I wish the login page should be an exception when checking the auth. I may be doing something wrong which I am not able to get. here goes my code.
routes.php
Route::post('login', 'Auth\AuthController#login');
Route::get('login' , 'Auth\AuthController#showLoginForm');
Route::get('/' , 'Auth\AuthController#showLoginForm');
kernel.php
protected $routeMiddleware = [
'auth' => \App\Http\Middleware\Authenticate::class,
'auth.basic' => \Illuminate\Auth\Middleware\AuthenticateWithBasicAuth::class,
'can' => \Illuminate\Foundation\Auth\Access\Middleware\Authorize::class,
'guest' => \App\Http\Middleware\RedirectIfAuthenticated::class,
'throttle' => \Illuminate\Routing\Middleware\ThrottleRequests::class,
'acl' => \App\Http\Middleware\CheckPermission::class,
];
Authenticate class
class Authenticate
{
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()->guest('login');
}
}
return $next($request);
}
}
AuthController class
class AuthController extends Controller {
use AuthenticatesAndRegistersUsers, ThrottlesLogins;
protected $redirectTo = '/dashboard';
protected $loginPath = '/login';
protected $redirectPath = '/dashboard';
public function __construct(){
$this->middleware('auth', ['except' =>'login']);
/* I have been trying these many things to fix this, all in loss.
// $this->middleware('acl'); // To all methods
// $this->middleware('acl', ['only' => ['create', 'update']]);
// $this->middleware('guest', ['only' => ['/login']]);
// echo "Message"; exit;
// $this->middleware('auth');
// $this->middleware('auth', ['only' => ['login']]);
// $this->middleware('auth', ['only' => ['/login']]);
// $this->middleware('auth', ['except' => 'login']);
// $this->middleware('guest');
// $this->middleware('guest', ['only' => ['logout' , 'login', '/login', '/']]);
}
Please help me, It going all above my head, seems some sort of rocket science to me. well btw I am new to laravel and may be doing some silly thing around, apologies for that. Thanks in Advance.
You need add route login outside Laravel group:
routes.php
Route::auth();
Route::group(['middleware' => 'auth'], function () {
// All route your need authenticated
});
Aditionally, you can see yours route list using:
php artisan route:list
Why you are doing all this just to redirect every non-logged in user to login form?
i think you can just do this
Routes.php
Route::post('login', 'Auth\AuthController#login');
Route::get('login' , 'Auth\AuthController#showLoginForm');
Route::get('/' , 'Auth\AuthController#showLoginForm');
Route::group(['middleware' => 'auth'], function () {
// any route here will only be accessible for logged in users
});
and auth controller construct should be like this
AuthController
public function __construct()
{
$this->middleware('guest', ['except' => 'logout']);
}
The problem is with your routes.
When I enter and I am not logged out you send me to login(get) route. And as you are specifying the middleware in the construct function in the AuthController, every time a method of the AuthController is called, construct function is called again and sends you back at login.. and it repeats indefinitely.
like #mkmnstr say
The problem is with your routes.
When I enter and I am not logged out you send me to login(get) route. And as you are specifying the middleware in the construct function in the AuthController, every time a method of the AuthController is called, construct function is called again and sends you back at login.. and it repeats indefinitely.
to fix that u should add
Auth::logout();
Here
...
} else {
Auth::logout(); // user must logout before redirect them
return redirect()->guest('login');
}
...
If your working with custom middleware you must follow it's all rules
in my case, I have to define a custom route class in the web middleware group.
In the world of copy-paste sometime we make mistakes.
Middleware :
public function handle($request, Closure $next)
{
if(!isset(session('user'))){
return redirect('login');
}
return $next($request);
}
}
My Mistake in Kernel.php
if custom middleware class present in web $middlewareGroups will check condition 2 times so it will give error as: redirected you too many times
protected $middlewareGroups = [
'web' => [
\App\Http\Middleware\webUser::class, //Remove
],
protected $routeMiddleware = [
'webUser'=> \App\Http\Middleware\webUser::class //Keepit
]
I had same problem after creating my own route service provider. The problem was that when I tried to login, in first time login page showed and after entering credentials I encountered "redirected too many times" and redirected to my admin dashboard and login route!
the solution was: adding middleware "web" into my routes:
Route::middleware('web')->group(base_path('Admin/routes.php'));

Laravel 5 redirects back to home after login

I have a page where users needs to login to click on a button, if they are not logged in they are taken to the login page to login. The problem is after the login they get redirected to home page. I would like them to be redirected back to the page they were before the login but can't get it to work.
The method of the login is still 100% standard. I have tried editing this function but with no luck.
public function postLogin(Request $request)
{
$this->validate($request, [
'email' => 'required|email', 'password' => 'required',
]);
$credentials = $request->only('email', 'password');
if ($this->auth->attempt($credentials, $request->has('remember')))
{
return redirect()->intended($this->redirectPath());
}
return redirect($this->loginPath())
->withInput($request->only('email', 'remember'))
->withErrors([
'email' => $this->getFailedLoginMessage(),
]);
}
If you simply want to redirect the user to a different page instead of the /home, just define a
protected $redirectTo = 'your-different-route'; // i.e. '/admin'
at the top of your AuthController
class AuthController extends Controller
{
use AuthenticatesAndRegistersUsers, ThrottlesLogins;
protected $redirectTo = 'admin/';
......
This should override the default route.
Anyway, in you wanna dig a bit deeper into the login system
return redirect()->intended($this->redirectPath());
is the key. Looking up to the intended method (Illuminate\Routing\Redirector) you will find something like this
public function intended($default = '/', $status = 302, $headers = [], $secure = null)
{
$path = $this->session->pull('url.intended', $default);
return $this->to($path, $status, $headers, $secure);
}
Then, you are injecting into the intended method $this->redirectPath(), defined as
public function redirectPath()
{
if (property_exists($this, 'redirectPath')) {
return $this->redirectPath;
}
return property_exists($this, 'redirectTo') ? $this->redirectTo : '/home';
}
Basically, every time the user performs a login, the system checks if there's a different intended route, if not it uses the default one (/home). You can change the default redirect route into the very redirectPath() method, but care, this is part of the laravel framework, so every time laravel gets an update, you might lose your changes. A safer solution is, like I said few lines above, override the redirect in the AuthController (uploads and stuff won't affect the controller).
EDIT
If you instead want to set up a custom redirect route for each login, Laravel ships with a convenient way to accomplish that right out of the box, and, once again, we are going to use the intended() method. Wherever you redirect the user to the login page, let's say the getLogin() method, you need to change the default redirect, something like
return view('auth.login');
to
return Redirect::guest('auth.login') //assuming that auth.login is your login view
With this simple fix, you are still redirecting the user to the login page, but using the guest() method instead:
public function guest($path, $status = 302, $headers = array(), $secure = null)
{
$this->session->put('url.intended', $this->generator->full());
return $this->to($path, $status, $headers, $secure);
}
Fairly straightforward, but, beside the standard redirect to(), it sets into session the intended variable equal to the current url BEFORE the actual redirection, i.e. the page where you wanna be redirected to.This is what is gonna save your day.
Last thing, within your postLogin() method, just set
return Redirect::intended('default-route');
You need to pass a default in case an intended location isn't provided in the session. Note that this is just a safety-plus, because by default, your postLogin() already has
redirect()->intended($this->redirectPath());
It uses by default redirectPath(), but now Redirect::guest() should provide an intended value.
You could use the Redirect->back() method:
if ($this->auth->attempt($credentials, $request->has('remember')))
{
return redirect()->back();
}
Although it's generally best to handle this in the Auth middleware.
More info can be found on the Laravel website.
please check this solution you might need to add
/**
* Where to redirect users after login.
*
* #var string
*/
protected $redirectTo = '/player';
/**
* The user has been authenticated.
*
* #param \Illuminate\Http\Request $request
* #param mixed $user
* #return mixed
*/
protected function authenticated(Request $request, $user)
{
//
return redirect()->route('homePlayer') ;
}
in your LoginController.php

Resources