【问题标题】:Laravel 8 rest api email verificationLaravel 8 rest api 电子邮件验证
【发布时间】:2021-03-24 21:16:51
【问题描述】:

在互联网和论坛中进行了大量搜索后,我放弃了...

我正在使用 Laravel 8 开发一个休息 api,我从一周开始就尝试使用 officiel documentation 进行电子邮件验证,一旦用户注册event(new Registered($user));
,电子邮件总是会成功发送 问题是,一旦我点击收到的电子邮件中的链接,我就会被重定向到登录页面(在这种情况下是一个帖子呼叫)..

这是我的路线/api.php:

Route::group(['namespace' => 'App\Http\Controllers', 'middleware' => ['api'], 'prefix' => 'auth'], function ($router) {
    Route::post('login', 'AuthController@login')->name('login');
    Route::post('register', 'AuthController@register');
    Route::post('logout', 'AuthController@logout');
    Route::post('profile', 'AuthController@profile')->middleware('verified');
    Route::post('refresh', 'AuthController@refresh');
});

Route::group(['namespace' => 'App\Http\Controllers', 'middleware' => ['api']],function ($router) {
    Route::get('/email/verify/{id}/{hash}', 'VerificationController@verify')->middleware(['auth', 'signed'])->name('verification.verify');
    Route::get('/email/resend', 'VerificationController@resend')->middleware(['auth', 'throttle:6,1'])->name('verification.send');
});

这里是我的 VerificationController:

<?php

namespace App\Http\Controllers;

use App\Http\Controllers\Controller;
use Illuminate\Http\Request;
use Illuminate\Foundation\Auth\EmailVerificationRequest;

class VerificationController extends Controller
{
    public function resend(Request $request)
    {
        $request->user()->sendEmailVerificationNotification();
        return response()->json(['message' => __('auth.email_sent')], Response::HTTP_NO_CONTENT);
    }

    public function verify(EmailVerificationRequest $request)
    {
        $request->fulfill();
        return response()->json(['message' => __('auth.user_verified_successfully')], Response::HTTP_RESET_CONTENT);
    }
}

最后但同样重要的是,我根据需要将 LogVerifiedUser 事件添加到 EventServiceProvider。

有什么建议吗?我试图从 verify 路由中删除中间件 auth,但这对我没有帮助...

PS:我正在使用 JWT 进行身份验证

【问题讨论】:

  • 您使用的是前端 SPA (React/Vue/Angular) 还是普通的多页应用程序?如果它是一个多页面应用程序,那么您的 web 中间件可能会将您重定向到登录页面。检查您的 web.php
  • 我正在使用前端 SPA(角度)

标签: php laravel laravel-8 email-verification


【解决方案1】:

我必须为我的其余 laravel 8 api 开发完全相同的功能,我与你分享我的工作,希望能够帮助你。

首先,您的问题是用户在单击验证链接后被重定向到登录页面。但问题是用户点击时是否在数据库中被标记为已验证?

如果单击后在数据库中标记为已验证,则该功能正在运行,但问题是重定向。因为如果您使用的是 Rest API,您可能希望将用户重定向到前端应用程序的登录或成功页面。

最后一个问题是你的中间件。首先在 api.php 文件中,连接的中间件是 'auth:api' 而不是 'auth'。但是一旦你不必将中间件放在验证路由上,否则你将不得不让用户连接,以便他验证他的电子邮件,并且由于你通过 API 路由,这很无聊......

最后是我选择的解决方案:

1.在你的 app/Models/User.php 中实现 MustVerifyEmail (通常,据我了解,你已经这样做了,但我更愿意把它放在以防其他人通过这个主题)

<?php

namespace App\Models;

use Illuminate\Contracts\Auth\MustVerifyEmail;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Foundation\Auth\User as Authenticatable;
use Illuminate\Notifications\Notifiable;
use Laravel\Passport\HasApiTokens;

class User extends Authenticatable implements MustVerifyEmail
{
    use HasFactory, Notifiable, HasApiTokens;

    /**
     * The attributes that are mass assignable.
     *
     * @var array
     */
    protected $fillable = [
        'name',
        'email',
        'password',
    ];

    /**
     * The attributes that should be hidden for arrays.
     *
     * @var array
     */
    protected $hidden = [
        'password',
        'remember_token',
    ];

    /**
     * The attributes that should be cast to native types.
     *
     * @var array
     */
    protected $casts = [
        'email_verified_at' => 'datetime',
    ];
}

2。在您的 app/Http/Controllers/AuthController.php 中为注册用户添加事件(通常,据我了解,您已经这样做了,但我更愿意将其放在以防其他人通过此主题)

<?php

namespace App\Http\Controllers;

use App\Models\User;
use Illuminate\Http\Request;
use Illuminate\Auth\Events\Registered;

class AuthController extends Controller
{
    public function register(Request $request)
    {
        $validatedData = $request->validate([
            'name' => 'required|max:55',
            'email' => 'email|required|unique:users',
            'password' => 'required|confirmed'
        ]);

        $validatedData['password'] = bcrypt($request->password);

        $user = User::create($validatedData);

        event(new Registered($user));

        $accessToken = $user->createToken('authToken')->accessToken;

        return response(['user' => $user, 'access_token' => $accessToken]);
    }

    public function login(Request $request)
    {
        $loginData = $request->validate([
            'email' => 'email|required',
            'password' => 'required'
        ]);

        if (!auth()->attempt($loginData)) {
            return response(['message' => 'Invalid Credentials']);
        }

        $accessToken = auth()->user()->createToken('authToken')->accessToken;

        return response(['user' => auth()->user(), 'access_token' => $accessToken]);
    }
}

3。在你的 routes/api.php 中定义了这个路由:


// Verify email
Route::get('/email/verify/{id}/{hash}', [VerifyEmailController::class, '__invoke'])
    ->middleware(['signed', 'throttle:6,1'])
    ->name('verification.verify');

// Resend link to verify email
Route::post('/email/verify/resend', function (Request $request) {
    $request->user()->sendEmailVerificationNotification();
    return back()->with('message', 'Verification link sent!');
})->middleware(['auth:api', 'throttle:6,1'])->name('verification.send');

4.创建app/Http/Controllers/VerifyEmailController.php

<?php

namespace App\Http\Controllers;

use Illuminate\Auth\Events\Verified;
use Illuminate\Http\RedirectResponse;
use Illuminate\Http\Request;
use Illuminate\Routing\Controller;
use App\Models\User;

class VerifyEmailController extends Controller
{

    public function __invoke(Request $request): RedirectResponse
    {
        $user = User::find($request->route('id'));

        if ($user->hasVerifiedEmail()) {
            return redirect(env('FRONT_URL') . '/email/verify/already-success');
        }

        if ($user->markEmailAsVerified()) {
            event(new Verified($user));
        }

        return redirect(env('FRONT_URL') . '/email/verify/success');
    }
}

解释:

通过这个解决方案,我们保留了通过电子邮件检查官方文档的所有操作。除了检查用户是否已连接来检索它并将他的电子邮件放入已验证之外。我们在控制器中启动一个方法,该方法将找到相应的用户进行验证。

我希望我是可以理解的,它可以帮助你:)

【讨论】:

  • 您从哪里获得 VerifyEmailController?它最初不在一个新的 Laravel 项目中。
  • @sba 你可以在答案4. Create app/Http/Controllers/VerifyEmailController.php找到它
  • @Ger 所以这是某人的发明?因为至少在 Laravel 8 中它不是开箱即用的
  • 是的@sba,显然是由 Matthieu Gellé 制作的,但是这周我一直在使用 Laravel 8 和 React 进行一些项目,当我尝试使用 API 时,所有这些东西都让我头疼方法,所以我所做的就是将 Inertia.js 添加到项目中,似乎 Laravel Auth 是为 web 而不是 api 设计的,现在一切都变得更容易了
猜你喜欢
  • 2021-02-15
  • 2019-02-21
  • 2021-04-28
  • 2020-03-18
  • 2020-02-25
  • 1970-01-01
  • 2019-02-12
  • 2017-06-23
  • 1970-01-01
相关资源
最近更新 更多