Laravel+Vue front-end and back-end separation project (four) mailbox verification and sliding verification

flow chart

Before doing business logic, we need to make a flow chart to ensure that the business logic that the user walks does not appear in an endless loop or fall into a dead end.

Effect picture

      

step 

1. Front-end page

src/views/login.vue
<template>
<input 
    class="input_box" 
    type="email" 
    v-model="email" 
    autocomplete="off"
    placeholder="Your email">
    <div class="pwd_note">{
   
   {email_note}}</div>
    <input 
        class="input_box" 
        type="password" 
        v-model="password" 
        autocomplete="off"
        placeholder="Your password">
    <div class="pwd_note">{
   
   {password_note}}</div>
        <div class="slider_vue">
        <div>
        <div @mousedown="slider_down" 
             :style="{'margin-left':left+'px'}"></div>
    </div>
    <div v-show="show_pic">
        <div :style="{'left':little_left+'px','top':true_top+'px','background-position-y':-true_top+'px','background-position-x':-true_left-50+'px'}"></div>
        <div :style="{'left':true_left+'px','top':true_top+'px'}"></div>
    </div>
</div>
</template>

<script>
methods:{
        login_event:function(){
            let that = this;
            let email_vertify = /^([a-zA-Z]|[0-9])(\w)+@[a-zA-Z0-9]+\.([a-zA-Z]{2,4})$/;
            if(that.email == ''){
                that.email_note = '请输入您的邮箱';
            }else if(!email_vertify.test(that.email)){
                that.email_note = '请输入正确格式的邮箱';
            }else{
                that.email_note = '';
            }
            let pwd_vertify = /^(\w){8,20}$/;
            if(that.password == ''){
                that.password_note = "请输入您的密码";
            }else if(!pwd_vertify.test(that.password)){
                that.password_note = '密码应为字母、数字组合的8-20位字符';
            }else{
                that.password_note = '';
            }
            if(that.email_note == '' && that.password_note == ''){
                let data={'email':that.email,'password':that.password};
                axios.post('/api/send',data).then(res=>{
                    if(res.data[0] == 3){   //登录成功
                        alert("state: "+res.data[0] + " note: " + res.data[1]);
                        that.$router.push('/person');
                    }else{
                        alert("state: "+res.data[0] + " note: " + res.data[1]);
                    }
                })
            }
        },
        slider_down:function(e){
            let that = this;
            that.show_pic = 1;
            if(!that.true_left)
                that.ran();
            let disX = e.clientX;
            let left_origin = that.left;
            let little_left_origin = that.little_left;
            document.onmousemove = (e) =>{
                let margin_left = e.clientX-disX;
                if(that.left >= 10 && that.left <=270){
                    that.left = left_origin + margin_left;
                    that.little_left = little_left_origin + margin_left;
                }
                if(that.left < 10){
                    that.left = 10;
                    that.little_left = 5;
                }
                if(that.left > 270){
                    that.left = 270;
                    that.little_left = 265;
                }
            },
            document.onmouseup = () => {
                document.onmousemove = null;
                document.onmouseup = null;
                if(that.true_left == that.little_left-50 ||
                that.true_left == that.little_left-51 ||
                that.true_left == that.little_left-49 ){
                    that.login_event();
                }
            }
        },
        ran:function(){
            let top_max = 100;
            let left_max = 195;
            this.true_top = Math.floor(Math.random() * top_max ) + 5;
            this.true_left = Math.floor(Math.random() * left_max ) + 20;
        }
    }
</script>

<style lang="scss">
.input_box{
    width:300px;
    border:0;
    border-bottom: 1px solid black;
    background-color: rgba(0,0,0,0);
    outline:none;
    padding: 10px;
    padding-top: 0;
    height: 30px;
}
.pwd_note{
    border:0;
    font-size: 15px;
    width: 310px;
    padding-left: 10px;
    text-align: left;
    height: 30px;
    margin-bottom: 30px;
    color:grey;
}
$slider_width:320px;
$slider_height:60px;
$ball_height:40px;
$picture_height:160px;
.slider_vue{
    width:$slider_width;
    height: $slider_height;
    margin-bottom: 30px;
    >div:first-child{
        width:$slider_width;
        height: $slider_height;
        background-image: url('/images/sign.png');
        background-size: cover;
        display: flex;
        align-items: center;
        border-radius: $slider_height;
        >div{
            width: $ball_height - 2px;
            height: $ball_height - 2px;
            border-radius: $ball_height;
            border:1px solid black;
            background-color: rgb(253, 227, 187);
        }
    }
    >div:last-child{
        animation: show 1s;
        width: $slider_width;
        height: $picture_height;
        background-color: rgb(184, 112, 112);
        position: relative;
        border-radius: 5px;
        bottom: $picture_height + $slider_height + 10px;
        background-image:url("/images/picture.jpg");
        display: flex;
        box-shadow: 0 0 5px black;
        >div{
            width: 50px;
            height: 50px;
            position: relative;
            border-radius: 5px;
        }
        >div:first-child{
            background-image: url('/images/picture.jpg');
            background-color: #fff;
            background-repeat: no-repeat;
            background-position-x: -150px;
            background-position-y: -30px;
            box-shadow: 0 0 10px black;
            left: 5px;
            top:30px;
            z-index: 10;
        }
        >div:last-child{
            background-color: rgba(0, 0, 0,0.3);
            box-shadow: 0 0 10px black inset;
            left: 100px;
            top:30px;
        }
    }
}
@keyframes show {
    0% {opacity: 0;}
    100% {opacity: 1;}
}
</style>

2. Apply for a 163 mailbox and set up stmp service

       

 3. Open port 465 on the server and configure the mailbox in the .env file of laravel:

MAIL_DRIVER=smtp
MAIL_HOST=smtp.163.com
MAIL_PORT=465
MAIL_USERNAME=你的邮箱@163.com
MAIL_PASSWORD=开启stmp的授权码
MAIL_ENCRYPTION=ssl
MAIL_FROM_ADDRESS=你的邮箱@163.com
MAIL_FROM_NAME="${APP_NAME}"

4. The user table of the database

CREATE TABLE `users` (
  `id` int(255) NOT NULL AUTO_INCREMENT,
  `nickname` varchar(10) CHARACTER SET utf8 NOT NULL DEFAULT 'nickname',
  `email` varchar(255) NOT NULL,
  `password` varchar(255) CHARACTER SET utf8 NOT NULL,
  `avatar` varchar(255) DEFAULT NULL,
  `token` varchar(255) DEFAULT NULL,
  `create_at` varchar(12) NOT NULL,
  `update_at` varchar(12) DEFAULT NULL,
  PRIMARY KEY (`id`,`email`)
) ENGINE=InnoDB AUTO_INCREMENT=5 DEFAULT CHARSET=latin1;

5. Routing and interface for sending mail

//发送验证邮件
Route::post('/send','UserController@send');

public function send(Request $request){
        $state[] = [];
        $email = $request->email;
        $password = $request->password;
        //查询是否已创建账户
        $user = DB::table('users')->where('email',$email)->first();
        if($user==null){//未创建,则创建账户,并发送验证邮件
            $time = date('YmdHis',time());
            $token = getString(15);
            $id = DB::table('users')->insertGetId([
                'nickname'=>'user_'.$time,
                'email'=>$email,
                'password'=>md5($password),
                'avatar'=>'/default_avatar.png',
                'create_at'=>time(),
                'token'=>$token
            ]);
            $subject = '揽阅LanYue邮箱验证';
            Mail::send('mail',['id'=>$id,'token'=>$token],
            function($message)use($email,$subject){
                $message->to($email);
                $message->subject($subject);
            });
            $state[0] = 0;
            $state[1] = "欢迎使用揽阅。您的账户还未激活,揽阅已为您发送激活邮件,请在十分钟内验证邮箱。";
        }else{//已创建
            if($user->update_at == null){ //未激活,发送验证邮件
                $token = getString(15);
                DB::table('users')->where('email',$email)->update([
                    'password'=>$password,
                    'token'=>$token
                ]);
                $subject = '揽阅LanYue邮箱验证';
                Mail::send('mail',['id'=>$user->id,'token'=>$token],
                function($message)use($email,$subject){
                    $message->to($email);
                    $message->subject($subject);
                });
                $state[0] = 1;
                $state[1] = "您的账户还未激活,揽阅已为您发送激活邮件,请在十分钟内验证邮箱。";
            }else{  //已激活
                if(md5($password) == $user->password){  //密码相同,登录
                    if(Cookie::get('token') == $user->token){
                        $state[0] = 2;
                        $state[1] = "您已登录,无需重复登录";
                    }else{
                        Cookie::queue('token', $user->token, 60);
                        $state[0] = 3;
                        $state[1] = "登录成功";
                        $state['id'] = $user->id;
                        $state['nickname'] = $user->nickname;
                        $state['avatar'] = $user->avatar;
                    }
                }else{  //登录失败
                    $state[0] = 3;
                    $state[1] = "密码错误";
                }
            }
        }
        return response()->json($state);
    }

6. Create a new blade template: resources/views/mail.blade.php

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<body>
    <div>您好,欢迎使用揽阅LanYue。请在十分钟内验证您的邮箱账户,谢谢配合!</div>
    <a href="http://www.***.com/vertify/{
   
   {$id}}/{
   
   {$token}}">点击验证</a>
</body>
</html>

7, vue routing and pages

src/route/index.js

import Vertify from '../views/Vertify.vue'

const routes = [
    ......
    {
        path:'/vertify/:id/:token',
        name:'vertify',
        component:Vertify
    }
]


src/view/Vertify.vue

<template>
    <div>
    </div>
</template>

<script>
import axios from 'axios';
export default {
    name:'vertify',
    data(){
        return{

        }
    },
    mounted(){
        let id = this.$route.params.id;
        let token = this.$route.params.token;
        axios.get('/api/vertify',{
            params:{'id':id,'token':token}
        }).then(res=>{
            alert(res.data);
        })
    }
}
</script>

8. Routing and interface for mail verification

//邮件验证
Route::get('/vertify','UserController@vertify');

public function vertify(Request $request){
        $state[] = [];
        $id = $request->id;
        $token = $request->token;
        $user = DB::table('users')->find($id);
        $update_at = time();
        if($user->token == ''){
            $state[0] = 0;
            $state[1] = "重复验证无效";
        }else if($update_at - $user->create_at > 600){
            $state[0] = 1;
            $state[1] = "验证过时,请重新发送验证邮件";
        }else if($token != $user->token){
            $state[0] = 2;
            $state[1] = "token错误,请重新发送验证邮件或联系客服";
        }else if($update_at - $user->create_at <= 600 && $token == $user->token){
            //token未过时且正确
            DB::table('users')->where('id',$id)->update([
                'update_at'=>$update_at
            ]);
            $state[0] = 3;
            $state[1] = "验证成功";
            $state['id'] = $user->id;
            $state['nickname'] = $user->nickname;
            $state['avatar'] = $user->avatar;
            Cookie::queue('token', $user->token, 60);
        }
        return response()->json($state);
    }

9. Obtain user information

Person.vue

mounted(){
    let that = this;
    axios.get('/api/userInfo').then(res=>{
      if(res.data[0] == 2){
        that.global.nickname = res.data['nickname'];
        that.global.nickpath = '/person';
        that.avatar = "http://lanyue.ink/api/"+res.data['avatar'];
        that.pre_avatar = "http://lanyue.ink/api/"+res.data['avatar'];
      }else{
        that.global.nickname = 'Login';
        that.global.nickpath = '/login';
        that.$router.push('/login');
      }
    });
},


//路由
Route::post('/userInfo','UserController@userInfo');
//接口
public function userInfo(){
        $state[] = [];
        $token = Cookie::get('token');
        if($token == null){
            $state[0] = 0;
            $state[1] = "找不到token";
        }else{
            $user = DB::table('users')->where('token',$token)->get();
            if($user[0] == null){
                $state[0] = 1;
                $state[1] = "token错误";
            }else{
                $state[0] = 2;
                $state[1] = "用户信息找到";
                $state['id'] = $user[0]->id;
                $state['nickname'] = $user[0]->nickname;
                $state['avatar'] = $user[0]->avatar;
            }
        }
        return response()->json($state);
    }

ok

Guess you like

Origin blog.csdn.net/qq_33514421/article/details/104996597