首页 > 解决方案 > 如何在使用 VerifiesEmail 功能实现的 laravel 6 API 中验证后使电子邮件验证链接过期?

问题描述

我已经实现了 Laravel 6 API 并使用了 Laravel 内置Illuminate\Foundation\Auth\VerifiesEmails 的基于教程here但是电子邮件验证链接没有过期并且在成功电子邮件验证后仍然可以访问。我发现了很多关于 laravel 前端的教程,但是如何在 API 上实现它。

验证ApiController

class VerificationApiController extends Controller
{
    use VerifiesEmails;

    /**
     * Mark the authenticated user's email address as verified.
     * @param  Request  $request
     * @return JsonResponse
     */
    public function verify(Request $request): JsonResponse
    {
        $userID = $request['id'];
        $user = User::findOrFail($userID);
        $date = date('Y-m-d g:i:s');

        // to enable the “email_verified_at field of that
        // user be a current time stamp by mimicking the
        // must verify email feature
        $user->email_verified_at = $date;
        $user->save();

        return response()->json('Email verified!');
    }

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

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

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

用户模型

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

    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',
    ];

    /**
     * Send email verification notification
     */
    public function sendApiEmailVerificationNotification()
    {
        $this->notify(new VerifyApiEmail); // my notification
    }
}

这是验证api路线

Route::get(‘email/verify/{id}’, ‘VerificationApiController@verify’)->name(‘verificationapi.verify’);
Route::get(‘email/resend’, ‘VerificationApiController@resend’)->name(‘verificationapi.resend’)

这是UsersApiController

<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
use App\User;
use Illuminate\Support\Facades\Hash;
use Auth;
use Validator;
use Illuminate\Foundation\Auth\VerifiesEmails;
use Illuminate\Auth\Events\Verified;
class UsersApiController extends Controller
{
use VerifiesEmails;
public $successStatus = 200;
/**
* login api
*
* @return \Illuminate\Http\Response
*/
public function login(){
if(Auth::attempt([‘email’ => request(‘email’), ‘password’ => request(‘password’)])){
$user = Auth::user();
if($user->email_verified_at !== NULL){
$success[‘message’] = “Login successfull”;
return response()->json([‘success’ => $success], $this-> successStatus);
}else{
return response()->json([‘error’=>’Please Verify Email’], 401);
}
}
else{
return response()->json([‘error’=>’Unauthorised’], 401);
}
}
/**
* Register api
*
* @return \Illuminate\Http\Response
*/
public function register(Request $request)
{
$validator = Validator::make($request->all(), [
‘name’ => ‘required’,
‘email’ => ‘required|email’,
‘password’ => ‘required’,
‘c_password’ => ‘required|same:password’,
]);
if ($validator->fails()) {
return response()->json([‘error’=>$validator->errors()], 401);
}
$input = $request->all();
$input[‘password’] = Hash::make($input[‘password’]);
$user = User::create($input);
$user->sendApiEmailVerificationNotification();
$success[‘message’] = ‘Please confirm yourself by clicking on verify user button sent to you on your email’;
return response()->json([‘success’=>$success], $this-> successStatus);
}
/**
* details api
*
* @return \Illuminate\Http\Response
*/
public function details()
{
$user = Auth::user();
return response()->json([‘success’ => $user], $this-> successStatus);
}
}

这是用户和身份验证路线

Route::post(‘login’, ‘UsersApiController@login’);
Route::post(‘register’, ‘UsersApiController@register’);
Route::group([‘middleware’ => ‘auth:api’], function(){
Route::post(‘details’, ‘UsersApiController@details’)->middleware(‘verified’);
}); // will work only when user has verified the email

所以问题是当我点击电子邮件上的验证链接时,用户已经过验证,但链接没有过期。我希望链接在用户通过验证后立即过期。怎么做?

标签: laravel-6email-verificationlaravel-api

解决方案


您是否实现了 VerifyApiEmail 类?

namespace App\Notifications;

use Illuminate\Support\Carbon;
use Illuminate\Support\Facades\URL;
use Illuminate\Auth\Notifications\VerifyEmail as VerifyEmailBase;

class VerifyApiEmail extends VerifyEmailBase
{
    protected function verificationUrl($notifiable)
    {
        return URL::temporarySignedRoute(
        'api.auth.verify', Carbon::now()->addMinutes(60), ['id' => $notifiable->getKey()]
        );
    }
}

您可以在此处添加以分钟、秒或小时为单位的过期时间。


推荐阅读