之前已经问过这个问题,我相信我的代码是正确的,但我的行为很奇怪。
我需要在登录后将用户重定向到不同的路由,具体取决于某些数据库值。我认为为了做到这一点,我只需将我的逻辑放在handle
app/Http/Middleware/RedirectIfAuthenticated.php
方法中。我的方法目前看起来像这样:
public function handle($request, Closure $next)
{
if ($this->auth->check()) {
if($this->auth->user()->sign_up_complete == 1){
return redirect('/');
} else {
if($this->auth->user()->step_one_complete == 0){
return redirect('/register/step-1');
} elseif($this->auth->user()->step_two_complete == 0){
return redirect('/register/step-2');
} else {
return redirect('/');
}
}
}
return $next($request);
}
这不起作用,登录后用户被重定向到/home
。我尝试将dd($this->auth->user())
置于$this->auth->check()
条件中,但它永远不会运行。如果我将它放在该检查之外,那么它就会在每次请求时运行。看起来$this->auth->check()
永远不会运行。
我的问题:如果不在这里,这个逻辑应该放在哪里?
我也从protected $redirectTo = '/account';
控制器中删除了AuthController.php
。
答案 0 :(得分:5)
您没有正确使用中间件。每当您登录时发送请求,这段代码就会触发。
要在登录后更改重定向位置,您可以覆盖AuthController中的redirectPath()
方法。 (您可以在vendor/laravel/framework/src/Illuminate/Foundation/Auth/RedirectsUsers.php
)
这看起来像这样:
...
public class AuthController extends Controller {
...
public function redirectPath()
{
if(Auth::user()->sign_up_complete == 1) {
return '/';
} else {
if(Auth::user()->step_one_complete == 0) {
return '/register/step-1';
} elseif(Auth::user()->step_two_complete == 0) {
return '/register/step-2';
} else {
return '/';
}
}
}
// The rest of the class implementation.
}
注意:我已使用Facade替代方法($this->auth()
)替换了Auth::
方法。仅仅因为我不确定AuthController是否有auth()
方法。
答案 1 :(得分:2)
我认为设置自定义中间件类以根据数据库值验证您的请求非常简单,我这样做是为了排除没有正确角色的用户。
该角色在我的用户表中定义,只允许具有管理员角色的用户访问系统。
namespace App\Http\Middleware;
use Closure;
use Illuminate\Support\MessageBag;
class RolesMiddleware
{
/**
* Handle an incoming request.
*
* @param \Illuminate\Http\Request $request
* @param \Closure $next
* @return mixed
*/
public function handle($request, Closure $next)
{
// If a user is authenticated
if(\Auth::user() != null)
{
// If the user doesn't have the correct role
if(\Auth::user()->role != 'administrator')
{
// logout the user
\Auth::logout();
// create a new MessageBag
$messageBag = new MessageBag;
// add a message
$messageBag->add('not_allowed', 'You are not allowed to login, because you do not have the right role!');
// redirect back to the previous page with errors
return \Redirect::to('login')->withErrors($messageBag);
}
}
return $next($request);
}
}
答案 2 :(得分:2)
解决方案是Mark Walet的回答,但需要稍加修正。返回应该是一个字符串:
public class AuthController extends Controller {
...
public function redirectPath()
{
if(Auth::user()->sign_up_complete == 1) {
return '/';
} else {
if(Auth::user()->step_one_complete == 0) {
return '/register/step-1';
} elseif(Auth::user()->step_two_complete == 0) {
return '/register/step-2';
} else {
return '/';
}
}
}
// The rest of the class implementation.
}
答案 3 :(得分:2)
高级答案:RedirectIfAuthenticated
的目的是防止已经通过身份验证的用户访问登录或注册路由/视图,因为他们已经登录。
测试:将登录视图添加为书签。然后登录。关闭浏览器或窗口。打开登录书签。您将直接去用户家或RedirectIfAuthenticated
中指定的地方。
出于LoginController的目的,创建一个redirecTo()
方法,该方法就是redirectPath()
方法的作用,以查看是否已自定义重定向。
// example
public function redirectTo()
{
switch (auth()->user()->role) {
case 'foo':
return route('foo.home');
case 'bar':
return route('bar.home');
default:
auth()->logout();
return route('web.welcome');
}
}
答案 4 :(得分:0)
你不能改变laravel的核心文件你需要做的就是添加这个代码 Auth \ AuthController
protected $redirectPath = '/dashboard';
答案 5 :(得分:0)
要了解从未到达路由逻辑的原因,您应该查看注册了RedirectIfAuthenticated中间件的app/Http/Kernel.php
:
protected $routeMiddleware = [
...
'guest' => \App\Http\Middleware\RedirectIfAuthenticated::class,
...
];
这意味着如果用户导航到不受guest
路由中间件保护的路由,则请求永远不会通过RedirectIfAuthenticated类,因此完全错过了您的逻辑。
您可以将访客中间件添加到路径文件中的注册路由,以强制路由通过您的代码,如下所示:
Route::get('/register/step-1', '<YOUR CONTROLLER METHOD>')->middleware('guest');
但是,既然您说用户已经登录(而不是访客),您应该按照其他答案的建议移动您的代码。
仅将此作为答案添加,因为无法在评论允许的空间内澄清。