使用 REST API 的 Laravel 电子邮件验证 5.7

Posted

技术标签:

【中文标题】使用 REST API 的 Laravel 电子邮件验证 5.7【英文标题】:Laravel Email Verification 5.7 using REST API 【发布时间】:2019-02-21 02:15:36 【问题描述】:

如何为 Rest API 重新制作 Laravel 5.7 电子邮件验证?

还是值得从头开始做所有事情?

【问题讨论】:

好吧,我实现了您的一段代码,并注意到您使用的是 POST 路由而不是 GET?电子邮件将参数作为 GET 发送,并会在该事件中引发未知方法异常。 我不记得我为什么这样做了。我重新回答了我的问题并改变了路线。谢谢! 【参考方案1】:

这个案例对我有用。完整项目代码here.

1) 重新设计的 VerificationController 控制器

删除重定向并做出response()->json(...) 响应。

<?php

namespace App\Http\Controllers\API\Auth;

use App\Http\Controllers\Controller;
use Illuminate\Foundation\Auth\VerifiesEmails;
use Illuminate\Http\Request;
use Illuminate\Auth\Events\Verified;

class VerificationController extends Controller

    use VerifiesEmails;

    /**
     * Show the email verification notice.
     *
     */
    public function show()
    
        //
    

    /**
     * Mark the authenticated user's email address as verified.
     *
     * @param  \Illuminate\Http\Request  $request
     * @return \Illuminate\Http\Response
     */
    public function verify(Request $request)
    
        // ->route('id') gets route user id and getKey() gets current user id() 
        // do not forget that you must send Authorization header to get the user from the request
        if ($request->route('id') == $request->user()->getKey() &&
            $request->user()->markEmailAsVerified()) 
            event(new Verified($request->user()));
        

        return response()->json('Email verified!');
//        return redirect($this->redirectPath());
    

    /**
     * Resend the email verification notification.
     *
     * @param  \Illuminate\Http\Request  $request
     * @return \Illuminate\Http\Response
     */
    public function resend(Request $request)
    
        if ($request->user()->hasVerifiedEmail()) 
            return response()->json('User already have verified email!', 422);
//            return redirect($this->redirectPath());
        

        $request->user()->sendEmailVerificationNotification();

        return response()->json('The notification has been resubmitted');
//        return back()->with('resent', true);
    

    /**
     * Create a new controller instance.
     *
     * @return void
     */
    public function __construct()
    
        $this->middleware('auth');
        $this->middleware('signed')->only('verify');
        $this->middleware('throttle:6,1')->only('verify', 'resend');
    

2) 添加了我的通知:

我这样做是为了让电子邮件中的链接指向我的前端并包含请求的临时SignedRoute 链接。

use Illuminate\Auth\Notifications\VerifyEmail as VerifyEmailBase;

class VerifyEmail extends VerifyEmailBase

//    use Queueable;

    /**
     * Get the verification URL for the given notifiable.
     *
     * @param  mixed  $notifiable
     * @return string
     */
    protected function verificationUrl($notifiable)
    
        $prefix = config('frontend.url') . config('frontend.email_verify_url');
        $temporarySignedURL = URL::temporarySignedRoute(
            'verification.verify', Carbon::now()->addMinutes(60), ['id' => $notifiable->getKey()]
        );

        // I use urlencode to pass a link to my frontend.
        return $prefix . urlencode($temporarySignedURL);
    

3) 添加配置frontend.php:

return [
    'url' => env('FRONTEND_URL', 'http://localhost:8080'),
    // path to my frontend page with query param queryURL(temporarySignedRoute URL)
    'email_verify_url' => env('FRONTEND_EMAIL_VERIFY_URL', '/verify-email?queryURL='),
];

4) 添加到用户模型中:

use App\Notifications\VerifyEmail;

/**
 * Send the email verification notification.
 *
 * @return void
 */
public function sendEmailVerificationNotification()

    $this->notify(new VerifyEmail); // my notification

5) 添加路线

以下路由在 Laravel 中使用:

// Email Verification Routes...
Route::get('email/verify', 'Auth\VerificationController@show')->name('verification.notice');
Route::get('email/verify/id', 'Auth\VerificationController@verify')->name('verification.verify');
Route::get('email/resend', 'Auth\VerificationController@resend')->name('verification.resend');

如果使用Auth::routes();,它们将被添加到应用程序中。

据我了解,Rest API 不需要 email/verify 路由及其在控制器中的方法。

6) 在我的前端页面/verify-email(来自frontend.php 配置)我向参数queryURL 中包含的地址发出请求

收到的 URL 如下所示:

"http://localhost:8000/api/email/verify/6?expires=1537122891&signature=0e439ae2d511f4a04723a09f23d439ca96e96be54f7af322544fb76e3b39dd32"

我的请求(带有授权标头):

await this.$get(queryURL) // typical get request

代码完美地验证了电子邮件,如果它已经被验证,我可以捕捉到错误。我也可以成功地将消息重新发送到电子邮件。

我是不是在某个地方犯了错误?如果您能改进一些东西,我将不胜感激。

【讨论】:

Privet ;) 我是 api 编程新手,我只是想知道,如果你有 auth()->user() 真的很安静吗? @nrkz 是的!但是你仍然需要使用tymon/jwt-auth 包(例如),它集成了内置授权,所以auth()-&gt;user() 有效。 我设法让它与您的代码一起使用。非常好。但是如何使用中间件来检查用户是否通过验证呢? @ИльяЗеленько auth()->user()->getKey() = null 我需要发送带有接收到的 URL 的 jwt 令牌吗? @ИльяЗеленько ,你怎么能在验证电子邮件时附加授权标头,因为它将是邮件中的链接,我只能在其中附加查询参数,我不知道你是怎么做到的? 【参考方案2】:

我试过 Илья Зеленько 答案,但我必须修改 VerificationController 构造方法如下

public function __construct()

    $this->middleware('auth')->except(['verify','resend']);
    $this->middleware('signed')->only('verify');
    $this->middleware('throttle:6,1')->only('verify', 'resend');

否则 laravel 需要 autentication 来访问验证和重新发送路由

【讨论】:

也许您应该完全删除$this-&gt;middleware('auth')-&gt;except(['verify','resend']);?由于只有两种方法:verifyresend。理论上也可以将$this-&gt;middleware('throttle:6,1')-&gt;only('verify', 'resend');替换为$this-&gt;middleware('throttle:6,1'); @ИльяЗеленько 这种修改不会带来安全风险吗?

以上是关于使用 REST API 的 Laravel 电子邮件验证 5.7的主要内容,如果未能解决你的问题,请参考以下文章

Laravel 5.3 Rest API 登录

Laravel 5 REST API

php 使用Passport进行Laravel REST API身份验证:https://www.cloudways.com/blog/rest-api-laravel-passport-authen

Laravel 7 - 使用 REST API 而不是数据库

使用 curl - JSON 访问 Laravel Rest API

Laravel REST API - 无限循环