laravel 8 : 注册后发送邮件验证 laravel

Posted

技术标签:

【中文标题】laravel 8 : 注册后发送邮件验证 laravel【英文标题】:laravel 8 : send email verification after registration laravel 【发布时间】:2021-09-25 21:47:44 【问题描述】:

我正在构建一个 laravel API。我希望当我注册时,邮箱验证会自动发送激活码到用户邮箱。

问题是当我创建一个新的激活码时,我也在令牌表中创建了一个新记录,这个记录有 user_id 字段,所以为了存储它,我使用 JWTAuth::user()->id 但我有这个错误:

试图获取非对象的属性“id”

我知道为什么会这样,因为我没有输入任何标记,我不知道如何处理它以及在标记表中创建新记录的位置

我有更多详细信息:

AuthController : Login and register

 public function register(Request $request) 

        $validator = Validator::make($request->all(), [
            'name'=>'required|string|min:3|max:30',
            'email' => 'required|string|email|max:100|unique:users',
            'password' => 'required|string|confirmed|min:6',
        ]);

        if($validator->fails())
            return response()->json($validator->errors()->toJson(), 400);
        

        $user = User::create(array_merge(
                    $validator->validated(),
                    ['password' => bcrypt($request->password)],
                ));

        $token = JWTAuth::fromUser($user);

        dd($this->sendNotification());

        $user->$this->sendNotification();

        return response()->json([
            'message' => 'successfully created',
            'user' => $user,
            'token' => $token,
        ], 201);
    

EmailVerifyController : for verify user email and validate activation code

public function emailVerify(Request $request)
        $data = $request->validate([
            'code' => 'required|size:10|numeric',
        ]);
        $interedCode = (int)$data['code'];//convert code from string to integer

        $userCode = Token::where('user_id' , JWTAuth::user()->id)->first();//find user from tokens table
        $activationCode = $userCode->code; //get activation code of user in tokens table
        $expires_in = (int)$userCode->expires_in; //get expire time of code

        $now = Carbon::now()->timestamp;


        if($interedCode == $activationCode) 
            if ($now < $expires_in) 
                    $user = JWTAuth::user()->id;
                    $findUser = User::find($user);
                    $findUser->email_verified_at = Carbon::now()->timestamp;
                    $findUser->save();

                    $token = Token::where('user_id', JWTAuth::user()->id)->first();
                    $token->status = 1;
                    $token->save();

                    return response()->json('email verified successfully', 200);
             else 
                return response()->json('code expired', 400);
            
        else
            return response()->json('wrong activation code' , 400);
        
    

SendNotificationTrait : for send email and create a new record in token table

trait EmailVerifyTrait

    public function sendNotification()

        $random = $this->generateVerificationCode(6);

        $details = [
            'title' => 'Mail from ItSolutionStuff.com',
            'body' =>$random,
        ];

        Mail::to('*****@gmail.com')->send(new VerifyMail($details));

        return response()->json([
            'message'=>'your email verification code sent to your email'
        ] , 201);
    

    public function generateVerificationCode($length = 6) 
        $characters = '0123456789';
        $charactersLength = strlen($characters);
        $code = '';
        for ($i = 0; $i < $length; $i++) 
            $code .= $characters[rand(0, $charactersLength - 1)];
        

            $token = new Token();
            $token->user_id = JWTAuth::user()->id;
            $token->code = $code;
            $token->status = 0;
            $token->save();
   
        return $code;


tokens tables : has this fields : user_id , code , created_at , expires_in

那么我该如何处理在令牌表中创建新的令牌记录?

还是应该使用事件监听器?

感谢您的帮助,对我的语言感到抱歉。

【问题讨论】:

【参考方案1】:

为了处理这个电子邮件验证,我使用了 laravel 通知:https://laravel.com/docs/8.x/notifications

我使用 $user->id 获取 id 并将其用于令牌表中的 user_id 字段。

代码:

注册方法

   use ActivationCode;

  public function register(Request $request) 

        $validator = Validator::make($request->all(), [
            'name'=>'required|string|min:3|max:30',
            'email' => 'required|string|email|max:100|unique:users',
            'password' => 'required|string|confirmed|min:6',
        ]);

        if($validator->fails())
            return response()->json($validator->errors()->toJson(), 400);
        

        //create user
        $user = User::create(array_merge(
                    $validator->validated(),
                    ['password' => bcrypt($request->password)],
                ));
        //create token
        $token = JWTAuth::fromUser($user);
        
        //create a new activation code
        $activationCode = $this->generateVerificationCode();
      
        //create a new token 
        $newToken = new Token;
        $newToken->code = $activationCode;
        $newToken->status = 0;
        $newToken->user_id = $user->id;
        $newToken->save();
    
        //email details
        $details = [
            'greeting' => 'Hi'.$request->name,
            'body' => 'use this activation code for verify your email address',
            'activation_code'=>$newToken->code,
            'thanks' => 'thank you',
            'order_id' => 101
        ];

        //send email verify to user email
        Notification::send($user, new EmailVerification($details));


        return response()->json([
            'message' => 'use created successfully and activation code sent to email',
            'user' => $user,
            'token' => $token,
        ], 201);
    

激活码特征

trait ActivationCode

    public function generateVerificationCode($length = 6) 
        $characters = '0123456789';
        $charactersLength = strlen($characters);
        $code = '';
        for ($i = 0; $i < $length; $i++) 
            $code .= $characters[rand(0, $charactersLength - 1)];
        
        return $code;
    
    

电子邮件验证通知

class EmailVerification extends Notification

    use Queueable;
    private $details;

    public function __construct($details)
        $this->details = $details;
    

    public function via($notifiable)
    
        return ['mail'];
    

    public function toMail($notifiable)
    
        return (new MailMessage)
                ->greeting($this->details['greeting'])
                ->line($this->details['body'])
                ->line($this->details['thanks'])
                ->line($this->details['activation_code']);
    


    public function toArray($notifiable)
    
        return [
            'order_id' => $this->details['order_id']
        ];
    



【讨论】:

以上是关于laravel 8 : 注册后发送邮件验证 laravel的主要内容,如果未能解决你的问题,请参考以下文章

Laravel 5.4 - 单击电子邮件中的验证链接时未传递或发送电子邮件验证令牌令牌。

Laravel 默认邮件不起作用

Laravel 5.7中的电子邮件验证语言文件

用户注册后如何发送验证/确认电子邮件

php 注册后发送验证邮件

[麦先生]在Laravel框架里实现邮箱验证---发送邮件