在 Laravel Jetstream / Fortify 中将登录用户重定向到配置文件页面(以启用 2 因素)?

Redirect logged-in User to Profile Page (to Enable 2-factor) in Laravel Jetstream / Fortify?

我一直在研究一种方法,如果用户没有为其个人资料启用 2 因素身份验证(理想情况下希望对所有路由都这样做),则将登录用户重定向到他们的个人资料页面。 我正在使用 Laravel 8、Fortify 和 Jetstream。

如果 two_factor_secret & two_factor_recovery_codesusers table 对于相关用户为 NULL。如果那些数据库列不是 NULL,它至少会被启用。一个可能检查的地方如下所示:

/app/Providers/FortifyServiceProvider.php

它默认设置:

$user = User::where('email', $request->email)->first();

验证登录,如果他们通过身份验证,我会做一些内务处理。

默认情况下,脚本末尾有一个return $user。

我可以检查 $user->two_factor_secret 是否在脚本中不为空,所以如果有可能以某种方式动态更改路线,那可能会奏效,至少在远初始登录是相关的,但我更愿意为应用程序中的每条路线检查他们的 2-factor 启用状态(只是状态,而不是代码)。我真的不清楚该怎么做?在某处的 ServiceProvider 中或 routes/web.php 等中。我想可以以某种方式将我的所有路由包装在一个组中,并且他们检查 [=37] 中的两步状态=].php 在处理请求的路由之前以某种方式?

如有任何帮助,我们将不胜感激。确实有两种选择。如果他们没有激活两步(即数据库字段填充数据),则在登录时只是一个警告和重定向到个人资料页面(/user/profile),然后更全局的选项总是重定向到个人资料页面任何路线,如果他们没有启用两步(这将阻止导航到个人资料页面以外的任何其他页面)。

谢谢。

我建议创建一个自定义 middleware,它可以应用于一组路由,这将确定经过身份验证的用户是否已启用 2FA

namespace App\Http\Middleware;

use Closure;

class HasTwoFactorAuthEnabled
{
    public function handle($request, Closure $next)
    {
        if (is_null(Auth::user()->two_factor_secret)) {
            return redirect(route('user.profile.2fa'));
        }

        return $next($request);
    }
}

在上面,如果经过身份验证的用户的 two_factor_secret 的值为 null,我们假设它未启用,因此重定向用户。否则请求继续到下一个中​​间件。

由于您可能不想对所有 HTTP 请求甚至所有 web 请求执行此检查,因此您需要在 $routeMiddleware 中注册中间件app/Http/Kernel.php.

中的数组
protected $routeMiddleware = [
    'has2FaEnabled' => \App\Http\Middleware\HasTwoFactorAuthEnabled::class,
];

然后您可以将中间件应用于单个路由或一组路由。例如;

Route::group(['middleware' => ['has2FaEnabled']], function () {
    Route::get('/profile', ProfileController::class);
});

现在,如果用户未启用 2FA,您是否 want/should 重定向用户实际上取决于您的用例和应用程序类型。如果安全对您很重要,或者您的应用程序中管理的数据很敏感,那么强制执行 2FA 可能是个好主意。否则,如果您只是提供 2FA 功能以提高安全性,我可能会建议避免强制用户启用它,而只是建议用户启用它或阻止访问某些 'sensitive' 功能(如果未启用) .

我不得不稍微调整一下中间件,让它在我的设置中运行:

<?php

namespace App\Http\Middleware;

use Closure;
use Illuminate\Support\Facades\Auth;
use Illuminate\Auth\Middleware\Authenticate as Middleware;

class HasTwoFactorAuthEnabled extends Middleware
{
    public function handle($request, Closure $next, ...$guards)
    {
        if (is_null(Auth::user()->two_factor_secret)) {
            session(['modal_message' => 'You Need to Enable 2-Factor Auth']);
            return redirect(route('profile.show'));
        }

        return $next($request);
    }
}

虽然这似乎有效,但在 web.php 中,只是作为测试:

Route::group(['middleware' => ['has2FaEnabled']], function () {
    Route::get('/', function () {
        return view('welcome');
    })->name('welcome');
});

我的 layouts/app.blade.php 中有处理模式消息的东西。我实际上也开始测试 Spatie 的 CSP 包的使用,这就是为什么那里有随机数的原因,尽管我最终想避免使用内联脚本。

<!-- The Modal -->
<div class="modal fade hide" id="myModal" data-keyboard="true" data-backdrop="true" tabindex='-1'>

    <div class="modal-dialog">
    <div class="modal-content">

      <!-- Modal Header -->
      <div class="modal-header">
        <h4 class="modal-title"></h4>
        <button type="button" class="close" data-dismiss="modal">&times;</button>
      </div>

      <!-- Modal body -->
      <div class="modal-body"></div>

      <!-- Modal footer -->
      <div class="modal-footer">
        <button type="button" class="uibuttonsmallred" data-dismiss="modal">Close</button>
      </div>

    </div>
    </div>
</div>
<?php
$modal_message = session('modal_message', false);
if ($modal_message !== false) {
?>
    <script nonce= "{{ csp_nonce() }}">
    $(window).on('load', function() {
        $('#myModal .modal-body').html('<?php echo $modal_message ?>');
        $('#myModal').modal('show');
    });
    </script>
<?php
}
?>

重定向到个人资料页面,在我的系统上是 profile.show。我应该能够处理剩下的事情。谢谢