首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Laravel5.7 MustVerifyEmail在多重认证系统中的应用

Laravel5.7 MustVerifyEmail在多重认证系统中的应用
EN

Stack Overflow用户
提问于 2018-11-07 09:37:19
回答 4查看 3.6K关注 0票数 2

我正在尝试将Laravel-5.7 MustVerifyEmail应用于多重身份验证系统。到目前为止,我所做的如下:

  1. 为“审计师”警卫创建了验证路线。
  2. 用新视图覆盖验证控制器中的显示方法。
  3. 在审计模型中实现了一个新的通知。
  4. 创建、注册和应用了一个名为“auditor.verified”的新中间件

在此过程之后,我发现它正在向电子邮件发送通知并显示验证页面,但是当我单击邮件中的“验证电子邮件地址”按钮时,它会用时间戳更新数据库,但它不会带我到重定向页面。相反,我在浏览器中得到“页面不工作”的消息。

我应该错过了一些东西。

这是项目档案 on GitHub

提前谢谢你的帮助。

EN

回答 4

Stack Overflow用户

回答已采纳

发布于 2018-11-11 05:11:27

最后,经过四天的研究,我终于解决了这个问题。

我修改了"EnsureEmailIsVerified“中间件如下:

代码语言:javascript
复制
<?php

namespace Illuminate\Auth\Middleware;

use Closure;
use Illuminate\Support\Facades\Redirect;
use Illuminate\Contracts\Auth\MustVerifyEmail;
use Illuminate\Support\Facades\Auth;

class EnsureEmailIsVerified
{

/**
 * Handle an incoming request.
 *
 * @param  \Illuminate\Http\Request  $request
 * @param  \Closure  $next
 * @return \Illuminate\Http\Response|\Illuminate\Http\RedirectResponse
 */
public function handle($request, Closure $next, $guard = null)
{

    $guards = array_keys(config('auth.guards'));

    foreach($guards as $guard) {

        if ($guard == 'admin') {

            if (Auth::guard($guard)->check()) {

                if (! Auth::guard($guard)->user() ||
                    (Auth::guard($guard)->user() instanceof MustVerifyEmail &&
                    ! Auth::guard($guard)->user()->hasVerifiedEmail())) {
                    return $request->expectsJson()
                            ? abort(403, 'Your email address is not verified.')
                            : Redirect::route('admin.verification.notice');
                }  

            }

        }

        elseif ($guard == 'auditor') {

            if (Auth::guard($guard)->check()) {

                if (! Auth::guard($guard)->user() ||
                    (Auth::guard($guard)->user() instanceof MustVerifyEmail &&
                    ! Auth::guard($guard)->user()->hasVerifiedEmail())) {
                    return $request->expectsJson()
                            ? abort(403, 'Your email address is not verified.')
                            : Redirect::route('auditor.verification.notice');
                }  

            }

        }

        elseif ($guard == 'web') {

            if (Auth::guard($guard)->check()) {

                if (! Auth::guard($guard)->user() ||
                    (Auth::guard($guard)->user() instanceof MustVerifyEmail &&
                    ! Auth::guard($guard)->user()->hasVerifiedEmail())) {
                    return $request->expectsJson()
                            ? abort(403, 'Your email address is not verified.')
                            : Redirect::route('verification.notice');
                    }  

                }
            }

        }

        return $next($request);
    }
}

这解决了我的问题。

票数 1
EN

Stack Overflow用户

发布于 2019-04-26 17:10:43

伊斯兰教的答案是好的,但要确保重写对EnsureEmailIsVerified的更改,而不是直接修改源文件。否则,无论何时执行$composer更新或推送到生产,您的更改都可能丢失。

票数 2
EN

Stack Overflow用户

发布于 2019-09-30 18:53:44

所以有一个类似的问题。

StackOverflow::路由[user.verification.notice]未定义/覆盖EnsureEmailIsVerified?

当使用多个警卫时,您只需在

代码语言:javascript
复制
App\Middleware\Authenticate.php

protected function redirectTo($request)
{
    if (! $request->expectsJson()) {
        if (Arr::first($this->guards) === 'admin') {
            return route('admin.login');
        }

        if (Arr::first($this->guards) === 'user') {
            return route('user.login');
        }

        return route('login');
    }
}

您只需将所有验证路由添加到您的web.php文件中,并更改指定的路由。

所有的航路都可以在

代码语言:javascript
复制
Illuminate\Routing\Router.php
\
/**
 * Register the typical authentication routes for an application.
 *
 * @param  array  $options
 * @return void
 */
public function auth(array $options = [])
{
    // Authentication Routes...
    $this->get('login', 'Auth\LoginController@showLoginForm')->name('login');
    $this->post('login', 'Auth\LoginController@login');
    $this->post('logout', 'Auth\LoginController@logout')->name('logout');

    // Registration Routes...
    if ($options['register'] ?? true) {
        $this->get('register', 'Auth\RegisterController@showRegistrationForm')->name('register');
        $this->post('register', 'Auth\RegisterController@register');
    }

    // Password Reset Routes...
    if ($options['reset'] ?? true) {
        $this->resetPassword();
    }

    // Email Verification Routes...
    if ($options['verify'] ?? false) {
        $this->emailVerification();
    }
}

/**
 * Register the typical reset password routes for an application.
 *
 * @return void
 */
public function resetPassword()
{
    $this->get('password/reset', 'Auth\ForgotPasswordController@showLinkRequestForm')->name('password.request');
    $this->post('password/email', 'Auth\ForgotPasswordController@sendResetLinkEmail')->name('password.email');
    $this->get('password/reset/{token}', 'Auth\ResetPasswordController@showResetForm')->name('password.reset');
    $this->post('password/reset', 'Auth\ResetPasswordController@reset')->name('password.update');
}

/**
 * Register the typical email verification routes for an application.
 *
 * @return void
 */
public function emailVerification()
{
    $this->get('email/verify', 'Auth\VerificationController@show')->name('verification.notice');
    $this->get('email/verify/{id}/{hash}', 'Auth\VerificationController@verify')->name('verification.verify');
    $this->post('email/resend', 'Auth\VerificationController@resend')->name('verification.resend');
}

因此,与其使用Auth:: routes (),不如手动将这些添加到您的web.php路由文件中,然后只给它们命名路由。

注意:一旦更改了指定的路由,就需要在视图中正确引用它们。

它会抱怨的第一件事是通知邮件,它引用默认的命名路由.

通过下面的示例,您可以在验证邮件过程和忘记密码密码过程中完成此操作。

忘记密码自定义名为路由和电子邮件

要实现这一点,您必须通过创建两个覆盖两个默认通知的自定义通知来覆盖电子邮件通知。

您将模仿文件中的laravel默认结构。

代码语言:javascript
复制
Illuminate\Auth\Notifications\VerifyEmail.php
Illuminate\Auth\Notifications\ResetPassword

一旦您创建了2个通知邮件程序。

例如

代码语言:javascript
复制
php artisan make:notification MailEmailVerificationNotification

,它在App\Notifications\MailEmailVerificationNotification中创建一个有效复制Illuminate\Auth\Notifications\VerifyEmail.php文件的文件。

您将将该方法添加到模型中。Laravel默认是用户,但如果您使用的是多个租户的自定义守卫,您将将此应用于您的相关模型。

然后,您将得到关于您的模型的以下内容

代码语言:javascript
复制
/**
 * Send the password reset notification.
 * App\Notifications\MailResetPasswordNotification.php
 *
 * @param  string  $token
 * @return void
 */
public function sendEmailVerificationNotification()
{
    $this->notify(new MailEmailVerificationNotification());
}

使用此路径更好,因为您重写了Laravel默认逻辑,但不编辑任何Laravel特定文件,这意味着它们在更新Laravel时不会被覆盖,并且只有在is设计更改时才会受到影响,比如最近将Laravel UI提取到自己的包中,这在重置路径上稍微改变了一些内容。

您可能会注意到我们更改了App\中间件\身份验证文件..。此文件不是供应商文件的一部分,虽然作为基本安装的一部分提供给您,但它的左侧供您更改、更新和更改……我们所做的改变只是为了容纳警卫,而不是大范围的改变,这允许多租户或不适用于应用程序。

对于任何人来说,我都希望这能有所帮助,我走上了一段学习这段路的旅程,希望能在我忘记的时候参考这一点,并希望它能帮助任何走类似道路的人。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/53186788

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档