邮箱有效性验证模块的设计

作者: Dearmadman | 来源:发表于2016-07-20 18:06 被阅读699次

    邮箱验证设计

    在应用开发中,邮件验证是一个常用的功能,它要求用户对其邮箱地址的有效性进行验证,一般流程为:

    • 用户在注册时填写邮箱地址
    • 在注册成功时,应用自动发送一封确认邮箱有效性的邮件,在邮件中附上效验地址
    • 用户访问效验地址以验证邮箱有效性

    功能需求

    • 用户注册时对用户的邮箱地址发送效验邮件
    • 需要对用户和邮箱以及校验码进行映射以验证用户邮箱的有效性

    功能分析

    • 应该具有邮件发送的功能
    • 效验的邮件应该具有时效性
    • 需要一张邮箱效验的表,用于存储用户和邮箱及校验码

    数据库设计

    `mail_verifies`: 
      - integer `id` increments
      - integer `user_id`
      - string 'mail'
      - string `code`
      - boolean `expired` default:false
      - datetime `created_at`
      - datetime `updated_at`
    

    职责分析

    我们分析整个流程应该不难发现,整个流程突出几个职责:

    • 唯一效验码的生成
    • 发邮件
    • 对效验码进行验证

    我们将生成校验码和对校验码进行验证的职责封装到 MailVerifier 类中,发邮件就直接使用 Laravel 中的邮件服务

    编码设计

    我们先设计用于效验邮件的路由:

    Route::get('mail-verification/{userId}/{code}', 'MailController@verify');
    

    我们需要在用户对象中设计一个发送验证邮件的方法:

    Class User {
    
      public function sendEmailVerification (Mailer $mailer, MailVerifier $mailVerifier) {
        if ($this->eamil_verified) {
          return false;
        }
    
        $data = [
        'user' => $this, 
        'code' => $mailVerifier->create($this->id, $this->email)->code
        ];
        $mailer->send('mail-verifier', $data, function ($message) {
          // ...
        });
      }
    
      public function setMailVerified () {
        $this->email_verified = true;
        $this->save();
      }
    }
    

    我们需要一个验证器类来进行校验码的生成和对效验码进行验证:

    use Carbon\Carbon;
    
    class MailVerifier {
      protected $mailVerify;
    
      public function __construct(MailVerify $mailVerify) {
        $this->$mailVerify = $mailVerify 
      }
    
      public function create ($userId, $mail) {
        $this->mailVerify->expiredAll($userId);
        return $this->mailVerify->create([
                'user_id' => $userId,
                'mail' => $mail,
                'code' => $this->generateCode($userId)
              ]);
      } 
    
      public function generateCode($userId) {
        return md5(time() . $userId . str_pod(rand(0, 999999), 6, '0'));
      }
    
      public function verify ($mail, $code) {
        $finder = $this->mailVerify->where([
          'mail' => $mail,
          'code' => $code,
          'expired' => false
          ])->where('created_at', '>', Carbon::now()->subMinute(10))->first();
    
        if ($finder) {
          $finder->setExpired();
        }
    
        return !!$finder;
      }
    }
    

    接着就是控制器了:

    class MailController extends Controller
    {
      protected $mailVerifier;
      protected $user;
    
      pbulic function __construct(User $user, MailVerifier $mailVerifier) {
        $this->user = $user;
        $this->mailVerifier = $mailVerifier; 
      }
    
      public function verify ($userId, $code) {
        $user = $this->uesr->find($userId);
    
        if (!$user) {
          return redirect('404');
        }
    
        $result = $this->mailVerifier->verify($user->eamil, $code);
        if ($result) {
          $user->setMailVerified();
          return view('mail-verified');
        }
        return redirect('404');
    
      }
    }
    

    PS: 欢迎关注简书 Laravel 专题,也欢迎 Laravel 相关文章的投稿 :)

    相关文章

      网友评论

      • itcjj:这是PHP么?
      • d39dd50c1293:请教一下,那个User跟Mailverfier这两个类是模型?

      本文标题:邮箱有效性验证模块的设计

      本文链接:https://www.haomeiwen.com/subject/wsvvjttx.html