zoukankan      html  css  js  c++  java
  • Laravel Email Verification via Api

    默认情况下,Laravel提供了一个web的邮箱验证路由,

    Laravel 的 AuthVerificationController 类包含了发送验证链接和验证 Email 的必要逻辑。通过将 verify 选项传给 Auth::routes 方法,就能为这个控制器注册所需要的路由:

    Auth::routes(['verify' => true]);

    没有api请求的。

    先复制一下Auth文件夹内的VerificationController.php文件,到Api文件夹下,主要用来参考。

    记得修改namespace

    批注 2020-04-15 002823

    然后在api.php文件中添加:

    Route::get('email/resend', 'ApiVerificationController@resend')->name('verification.resend');

    resend方法位于

    VerifiesEmails trait内:

    批注 2020-04-15 003225

    然后在api.php文件中添加:

    Route::get('email/verify/{id}/{hash}', 'ApiVerificationController@verify')->name('verification.verify');

    该方法同样位于VerifiesEmails trait内:

    批注 2020-04-15 003500

    如果需要重写上述两个方法,在ApiVerificationController.php文件中添加:

    /**
     * Mark the authenticated user's email address as verified.
     *
     * @param IlluminateHttpRequest $request
     * @return IlluminateHttpResponse
     *
     * @throws IlluminateAuthAccessAuthorizationException
     */
    

    public function verify(Request $request)
         {
             auth()->loginUsingId($request->route('id'));

            if ($request->route('id') != $request->user()->getKey()) {
                 throw new AuthorizationException;
             }

            if ($request->user()->hasVerifiedEmail()) {
                 return esponse(['message' => 'Already verified!']);
             }

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

            if ($response = $this->verified($request)) {
                 return $response;
             }

            return $request->wantsJson()
                 ? new Response(['message' => 'Successfully verified!'], 204)
                 : redirect($this->redirectPath())->with('verified', true);
         }

    /**
     * Resend the email verification notification.
     *
     * @param IlluminateHttpRequest $request
     * @return IlluminateHttpResponse
     */
    public function resend(Request $request)
    {
        if ($request->user()->hasVerifiedEmail()) {
            return 
    esponse(['message' => 'Already verified!'], 204);
        }
    
        $request->user()->sendEmailVerificationNotification();
    
        return 
    esponse(['message' => 'Email Sent!'], 200);
    }
    

    因为是api请求,所以构造函数中修改

    $this->middleware('auth');
    

    为:

    $this->middleware('auth:api')->only('resend');
    

    记得将user模型类实现MustVerifyEmail接口:

    批注 2020-04-15 005108

    这个接口实现后才能使用user发送验证邮件:

    <?php
    
    namespace IlluminateContractsAuth;
    
    interface MustVerifyEmail
    {
        /**
         * Determine if the user has verified their email address.
         *
         * @return bool
         */
        public function hasVerifiedEmail();
    
        /**
         * Mark the given user's email as verified.
         *
         * @return bool
         */
        public function markEmailAsVerified();
    
        /**
         * Send the email verification notification.
         *
         * @return void
         */
        public function sendEmailVerificationNotification();
    
        /**
         * Get the email address that should be used for verification.
         *
         * @return string
         */
        public function getEmailForVerification();
    }
    
    

    接下来用Postman测试注册请求:

    批注 2020-04-15 005334

    注册成功,拿到token:

    批注 2020-04-15 005414

    然后设置token,发送请求至http://laravelauth.test/api/email/resend

    批注 2020-04-15 005636

    结果如下:

    批注 2020-04-15 005715

    打开Laravel.log文件可以看到发送了:

    批注 2020-04-15 005833

    拷贝这个链接,在postman中测试发送get请求至这个链接:

    注:图上id已经是4了,因为我测试了几次发送再截的图。

    批注 2020-04-15 012929

    因为请求了第二次:

    批注 2020-04-15 013020

    我们添加一个api route测试验证的结果:

    Route::get('verified-only', function (Request $request) {
        dd('You Are Verified!', $request->user()->name);
    })->middleware('auth:api', 'verified');
    
    

    批注 2020-04-15 013457

    Postman中测试如下:

    未登录的【无auth token的】

    批注 2020-04-15 013554

    登录了的【有token的】:

    批注 2020-04-15 013637

    附上最后的代码:

    User.php

    <?php
    
    namespace App;
    
    use AppNotifications	estPasswordResetEmailNotification;
    use IlluminateContractsAuthMustVerifyEmail;
    use IlluminateDatabaseEloquentSoftDeletes;
    use IlluminateFoundationAuthUser as Authenticatable;
    use IlluminateNotificationsNotifiable;
    use LaravelPassportHasApiTokens;
    
    class User extends Authenticatable implements MustVerifyEmail
    {
        use Notifiable, HasApiTokens, SoftDeletes;
    
        /**
         * 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',
        ];
    
        public function sendPasswordResetNotification($token)
        {
            $this->notify(New testPasswordResetEmailNotification($token));
        }
    
        public function tasks()
        {
            return $this->hasMany(Task::class);
        }
    }
    
    

    api.php

    <?php
    
    use IlluminateHttpRequest;
    use IlluminateSupportFacadesRoute;
    
    /*
    |--------------------------------------------------------------------------
    | API Routes
    |--------------------------------------------------------------------------
    |
    | Here is where you can register API routes for your application. These
    | routes are loaded by the RouteServiceProvider within a group which
    | is assigned the "api" middleware group. Enjoy building your API!
    |
    */
    
    Route::middleware('auth:api')->get('/user', function (Request $request) {
        return $request->user();
    });
    
    Route::middleware('auth:api')->get('/user', function (Request $request) {
        return $request->user();
    });
    
    //Route::get('verified-only', function (Request $request) {
    //    dd('You Are Verified!', $request->user()->name);
    //})->middleware('auth:api', 'verified');
    
    Route::post('login', 'ApiAuthController@login')->name('login.api');
    Route::post('register', 'ApiAuthController@register')->name('register.api');
    
    Route::middleware('auth:api')->get('logout', 'ApiAuthController@logout')->name('logout.api');
    
    Route::post('/password/email', 'ApiForgotPasswordController@sendResetLinkEmail');
    Route::post('/password/reset', 'ApiResetPasswordController@reset');
    
    Route::apiResource('tasks', 'TaskController')->middleware('auth:api');
    
    Route::get('email/resend', 'ApiVerificationController@resend')->name('verification.resend');
    Route::get('email/verify/{id}/{hash}', 'ApiVerificationController@verify')->name('verification.verify');
    
    

    VerificationController

    <?php
    
    namespace AppHttpControllersApi;
    
    use AppHttpControllersController;
    use AppProvidersRouteServiceProvider;
    use IlluminateAuthAccessAuthorizationException;
    use IlluminateAuthEventsVerified;
    use IlluminateFoundationAuthVerifiesEmails;
    use IlluminateHttpRequest;
    use IlluminateHttpResponse;
    
    class VerificationController extends Controller
    {
        /*
        |--------------------------------------------------------------------------
        | Email Verification Controller
        |--------------------------------------------------------------------------
        |
        | This controller is responsible for handling email verification for any
        | user that recently registered with the application. Emails may also
        | be re-sent if the user didn't receive the original email message.
        |
        */
    
        use VerifiesEmails;
    
        /**
         * Where to redirect users after verification.
         *
         * @var string
         */
        protected $redirectTo = RouteServiceProvider::HOME;
    
        /**
         * Create a new controller instance.
         *
         * @return void
         */
        public function __construct()
        {
            //修改為api
            $this->middleware('auth:api')->only('resend');
            // 'signed'中間件 => IlluminateRoutingMiddlewareValidateSignature::class,
            $this->middleware('signed')->only('verify');
            //1分鐘内最多只能發送6次請求
            $this->middleware('throttle:6,1')->only('verify', 'resend');
        }
    
        /**
         * Mark the authenticated user's email address as verified.
         *
         * @param IlluminateHttpRequest $request
         * @return IlluminateHttpResponse
         *
         * @throws IlluminateAuthAccessAuthorizationException
         */
        public function verify(Request $request)
        {
            auth()->loginUsingId($request->route('id'));
    
            if ($request->route('id') != $request->user()->getKey()) {
                throw new AuthorizationException;
            }
    
            if ($request->user()->hasVerifiedEmail()) {
                return 
    esponse(['message' => 'Already verified!']);
            }
    
            if ($request->user()->markEmailAsVerified()) {
                event(new Verified($request->user()));
            }
    
            if ($response = $this->verified($request)) {
                return $response;
            }
    
            return 
    esponse(['message' => 'Successfully verified!']);
        }
    
        /**
         * Resend the email verification notification.
         *
         * @param IlluminateHttpRequest $request
         * @return IlluminateHttpResponse
         */
        public function resend(Request $request)
        {
            if ($request->user()->hasVerifiedEmail()) {
                return 
    esponse(['message' => 'Already verified!'], 204);
            }
    
            $request->user()->sendEmailVerificationNotification();
    
            return 
    esponse(['message' => 'Email Sent!'], 200);
        }
    }
    
    
  • 相关阅读:
    ServiceStack支持跨域提交
    CookiesHelper
    poj 3669 线段树成段更新+区间合并
    poj2528 线段树+离散化
    hdu3308 线段树 区间合并
    hdu1542矩阵的并 线段树+扫描线
    hdu1255 矩阵的交 线段树+扫描线
    简单单点更新线段树
    树状数组模版
    hdu1873优先队列
  • 原文地址:https://www.cnblogs.com/dzkjz/p/12702598.html
Copyright © 2011-2022 走看看