0

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

如果用户表中的two_factor_secrettwo_factor_recovery_codes对于相关用户为 NULL,则似乎未启用 2 因子。如果这些 DB 列不为 NULL,则至少启用它。一个可能检查的地方如下所示:

/app/Providers/FortifyServiceProvider.php

它默认设置:

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

验证登录,然后如果他们通过身份验证,我会做一些家务。

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

我可以检查脚本中的 $user->two_factor_secret 是否不为空,所以如果有可能以某种方式动态更改路由可能会起作用,至少就初始登录而言,但我会更喜欢检查应用程序中每条路线的 2 因素启用状态(只是状态,而不是代码)。我不太清楚该怎么做?在某处的ServiceProvider中或在routes/web.php等中。我想有可能以某种方式将我的所有路由包装在一个组中,并且他们在处理之前以某种方式检查routes/web.php中的两步状态要求的路线?

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

谢谢。

4

2 回答 2

1

我建议创建一个自定义中间件,它可以应用于一组路由,这将确定经过身份验证的用户是否已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请求执行此检查,因此您需要将中间件注册$routeMiddlewareapp/Http/Kernel.php.

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

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

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

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

于 2021-06-27T12:46:23.427 回答
0

我必须稍微调整中间件才能让它在我的设置上工作:

<?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。我应该能够处理剩下的事情。谢谢。

于 2021-06-27T17:34:44.997 回答