Laravel意外重定向(302)

32

我开始了一个新的 Laravel 5.2 项目,使用 laravel new MyApp 命令,并通过 php artisan make:auth 命令添加了身份验证。这个网站是为会员专属设计的,第一个用户是种子用户(seeded),并创建其他用户(不需要手动创建用户/密码重置等操作)。

这些是我目前定义的路由:

 Route::group(['middleware' => 'web'], function () {
  // Authentication Routes...
  Route::get( 'user/login',  ['as' => 'user.login',     'uses' => 'Auth\AuthController@showLoginForm']);
  Route::post('user/login',  ['as' => 'user.doLogin',   'uses' => 'Auth\AuthController@login'        ]);

  Route::group(['middleware' => 'auth'], function() {
    // Authenticated user routes
    Route::get( '/', ['as'=>'home', 'uses'=> 'HomeController@index']);
    Route::get( 'user/{uid?}', ['as' => 'user.profile',   'uses' => 'Auth\AuthController@profile' ]);
    Route::get( 'user/logout', ['as' => 'user.logout',    'uses' => 'Auth\AuthController@logout'  ]);
    Route::get( '/user/add',   ['as' => 'user.add',       'uses' => 'Auth\AuthController@showAddUser']);

    [...]
  });
});

我可以正常登录,但是我遇到了一些非常“奇怪”的行为 - 当我尝试退出(通过使用由artisan创建的内置logout方法),页面会进行302重定向到主页,并且我仍然登录着。

更重要的是,虽然几乎所有页面(未在此处列出)都按预期工作,但user.add也会产生302重定向到主页。

请注意,主页被声明为AuthController的$redirectTo,如果这有任何区别。

我通过debugbar发现了这些重定向。有什么建议需要查找的问题吗?


对于那些最近升级了 Laravel 的人,请检查您控制器中的中间件语法。很可能需要更新。 - Marcel Gruber
14个回答

27

我有同样的问题,通过添加带有accept:'application/json'的头解决了。 我认为在此之前我检查过源代码,发现如果您没有添加这个头,在使用auth中间件时可能会重定向。但是我不确定是否是这种情况,也无法回忆起我在哪里找到了这个信息。


12
我可以确认这个解决方案对我有用。请求无效($this->validate($request...) 返回重定向),但 Laravel 没有检测到该请求是来自 Ajax,所以它试图重定向而不是返回一个 JSON 对象。我使用的是 Laravel 5.3 版本。 - Fran Cano
我可以确认同样的事情,突然间我得到了这种行为,除了缺少“Accept”头告诉它接受“application/json”而不是“*/*”。 - dbf
在Laravel中也遇到了同样的问题,花了几个小时在Insomnia中测试API并且一头雾水。 - Boardy

20

经过几个小时的折磨,我找到了答案——而且很傻。

问题在于路由user.profile有一个路径user/{uid?},它匹配了user/logoutuser/add这两个路径。

因为它在其他路径之前,并且没有正则表达式或类似的东西,所以它处理了该路由。

我仍然不知道为什么会对那个页面生成302,但我发现将它从AuthController中移出并放入UserController(从一开始就应该放在那里)可以解决这个问题。

因此,我的(修订后可用的)路由现在看起来像这样:

Route::group(['middleware' => 'web'], function () {
  // Authentication Routes...
  Route::get( 'user/login',  ['as' => 'user.login',     'uses' => 'Auth\AuthController@showLoginForm']);
  Route::post('user/login',  ['as' => 'user.doLogin',   'uses' => 'Auth\AuthController@login'        ]);

  Route::group(['middleware' => 'auth'], function() {
    // Authenticated user routes
    Route::get( '/',     ['as'=>'home', 'uses'=> 'HomeController@index']);
    Route::get( '/home', ['as'=>'home', 'uses'=> 'HomeController@home']);
    Route::get( 'user/logout', ['as' => 'user.logout',    'uses' => 'Auth\AuthController@logout'  ]);

    // *** Added /profile/ here to prevent matching with other routes ****
    Route::get( 'user/profile/{uid?}', ['as' => 'user.profile',   'uses' => 'UserController@profile' ]);
    Route::get( '/user/add',           ['as' => 'user.add',       'uses' => 'UserController@showAddUser']);

    [...]
    });
});

+1 我整个下午都在为类似的问题苦苦挣扎。我从来没有想过要看路由的顺序。 - Peter Griffin

19

我在进行ajax请求时遇到了这个问题,我正在验证一些数据。要验证的字段与表单中的字段不匹配。 - Atnaize

11

对我来说,重要的是 guest 中间件!

这个中间件会在用户已经登录时将其重定向到主页。 对于 Api 请求,您无需使用它。因此我将其删除后问题得以解决。


太聪明了!我从来没有想到客人账单会是我的问题的原因。 - Adsy2010
这对我也是解决方法!非常感谢,伙计。 - James Stewart
你是如何移除它们的? - redvivi

1
可能默认的注销重定向页面是“主页”,但似乎您的“web”路由中没有“主页”。请在您的“AuthController.php”中尝试以下代码。
use AuthenticatesAndRegistersUsers, ThrottlesLogins; // after this line
$redirectAfterLogout = 'login' // add this line

这将在注销后将您重定向到登录页面。如果您希望,可以将其更改为任何路由。我使用登录作为示例。 或者 您可以在\vendor\laravel\framework\src\Illuminate\Foundation\Auth\AuthenticatesUsers.php中更改注销后的路由。
public function logout()
    {
        Auth::logout();

        return redirect(property_exists($this, 'redirectAfterLogout') ? $this->redirectAfterLogout : 'login');
    }

我将默认路由更改为login。如果您的AuthController.php中没有$redirectAfterLogout,它将在此处查找重定向路径。我不建议人们在这里进行编辑,这有点像硬编码。


Route::get('/', ['as'=>'home', 'uses'=> 'HomeController@index']); 这是一个名为 home 的路由,但是除非您已登录,否则无法访问它。不过,从 logout 进行的 redirect 操作默认会返回到 login 页面。 - Tim Lewis
如上所述,“home”是路由的名称--我看到的是请求发送到“AuthController@logout”,然后被重定向到“HomeController@index”。 - Nick Andriopoulos

1
如果您的网站没有使用HTTPS,您需要在.env文件中定义以下属性。
SESSION_SAME_SITE=Strict

注意:某些浏览器采取此预防措施以防止恶意网站利用用户。

1
对于我在保存过程中遇到的302状态,解决方法是在ajax头部插入Accept: application/json,因为我在php文件中有一个脚本。
               $.ajax({
                url:'{{route('fetchMunCit')}}' +'/'+id,
                type:'GET',
                dataType:'json',
                Accept: application/json
                    success:function(response)

1
我遇到了这个问题,结果发现我在我的ajax控制器中有一个route:redirect。 这是没有意义的,因为显然我们必须返回ajax,但我却返回了一个route!

1
我经常使用ajax(get和post),每次响应时都会使用服务器上的session()->regenerate()更新令牌,然后在客户端使用js更新每个令牌字段。但是上周,我不小心删除了这个一行代码。所以,系统在第二次调用后突然开始给出302响应。很难找到问题所在,因为有时它可以正常工作(第一次),有时不能正常工作。我意识到这是令牌不匹配后,花了几天时间努力寻找原因,因为响应没有指向令牌不匹配,只有302重定向。最终,我通过在tokensMatch()函数中dd()两个令牌来找到问题。我不知道为什么它不会触发TokenMismatch。希望这个轶事能帮助你。

1

我也遇到了此问题,之前登录页面正常工作。于是我查看了目录权限,结果如下:

drwxr-xr-x  7 user user     4096 Jun 27  2019 storage

所以存储目录具有755权限,这意味着只有所有者拥有写访问权限,由于该目录属于“用户”,其他像laravel这样的程序无法将内容写入其中。

使用此命令将目录更改为777解决了我的问题:

sudo chmod 777 -R PROJECT_PATH/storage

正确的方法,

由于将目录设为全局可写并不是正确的方法,因此将该目录归属于apache,并将存储设置为775即可使其再次正常工作。

sudo chown -R user:www-data PROJECT_PATH/storage
sudo chmod 775 -R PROJECT_PATH/storage

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接