Laravel Email Verification 5.7 using REST API Laravel Email Verification 5.7 using REST API laravel laravel

Laravel Email Verification 5.7 using REST API


This case works for me. Full project code here.

1) Redesigned VerificationController controller

Removed redirects and made response()->json(...) responses.

<?phpnamespace 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) Added my Notification:

I made it so that the link in the email message led to my frontend and contained a temporarySignedRoute link for the request.

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) Added config 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) Added to User model:

use App\Notifications\VerifyEmail;

and

/** * Send the email verification notification. * * @return void */public function sendEmailVerificationNotification(){    $this->notify(new VerifyEmail); // my notification}

5) Added routes

The following routes are used in 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');

They are added to the application if used Auth::routes();.

As far as I understand the email/verify route and its method in the controller are not needed for Rest API.

6) On my frontend page /verify-email(from frontend.php config) i make a request to the address contained in the parameter queryURL

The received URL looks like this:

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

My request(with Authorization header):

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

The code perfectly verify the email and I can catch the error if it has already been verified. Also I can successfully resend the message to the email.

Did I make a mistake somewhere? Also I will be grateful if you improve something.


I tried Илья Зеленько answer but I must modify VerificationController construct method as follow

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

otherwise laravel need autentication to access verify and resend routes