Laravel6.0结合七牛云短信实现短信验证

前期准备

登录七牛云官网: https://developer.qiniu.com/

1、找到控制台–云短信–签名,新建签名,注意填写签名时不要填写模糊词语或者个人等词语,如果没有通过审核,客服会提示给你哪里错误,你就修改即可。

2、找到模板,新建模板,选择验证码类即可。

3、等待客服审核,一般半小时吧。

4、之所以选择七牛云,是因为七牛给我们免费试用300条短信,所以不用花钱哦。

创建项目

laravel new alipay

cd alipay

composer require laravel/ui

php artisan ui vue --auth

cnpm install

npm run dev

# 修改数据库配置后执行如下命令
php artisan migrate

# 安装七牛sdk
composer require qiniu/php-sdk

# 启动项目
php artisan serve  

项目配置

1、在 .env 文件中修改数据库相关配置,手动创建数据库,然后执行迁移命令 php artisan migrate

2、在 users 表中增加字段 mobileUser 模型中增加白名单

实现发手机短信

1、在 web.php 中添加路由并创建对应控制器和方法

Route::post('send', 'MessageController@send');

2、在 send 方法中添加如下代码:

use Illuminate\Http\Request;
use \Qiniu\Auth;

public function send(Request $request)
{
    $ak = "YouAccessKey";
    $sk = "YouSecretKey";
    $auth = new Auth($ak, $sk);
    $client = new \Qiniu\Sms\Sms($auth);

    //发送信息模块
    $template_id = "Youtemplate_id";
    $mobiles = array($request->mobile);
    
    // 由于我们做的是登录,所以需要验证手机号是否存在
    $mobile = User::where('mobile', $request->mobile)->find();
    if(!$mobile){
        return response()->json(['status'=>0, 'msg' => '手机号码不存在']);
    }

    $code = $this->GetRandStr(4);  // 随机生成短信验证码code,4代表验证码长度
    session(['code' => $code]);  // 把code存入session
    try {
        //发送短信
        $resp = $client->sendMessage($template_id, $mobiles, ['code' => $code]);
        print_r($resp);
    } catch (\Exception $e) {
        echo "Error:", $e, "\n";
    }
}

/***
 * 自定义方法生成随机验证码
 * @param $len
 * @return string
 */
private function GetRandStr($len)
{
    $chars = array("0", "1", "2", "3", "4", "5", "6", "7", "8", "9");
    $charsLen = count($chars) - 1;
    shuffle($chars);
    $output = "";
    for ($i = 0; $i < $len; $i++) {
        $output .= $chars[mt_rand(0, $charsLen)];
    }
    return $output;
}

以上写法参考资料:https://github.com/qiniu/php-sdk/blob/master/docs/sms/example.php

前端页面

我这里演示的前端模板是 laravel 命令自动生成的登录模板,稍作修改,代码如下:

@extends('layouts.app')

@section('content')
    <div class="container">
        <div class="row justify-content-center">
            <div class="col-md-8">
                <div class="card">
                    <div class="card-header">{{ __('Login') }}div>

                    <div class="card-body">
                        <form method="POST" action="{{ route('login') }}">
                            @csrf

                            <div class="form-group row">
                                <label for="mobile"
                                       class="col-md-4 col-form-label text-md-right">手机号:label>

                                <div class="col-md-4">
                                    <input type="text" class="form-control" id="mobile" name="mobile">
                                div>

                                <div class="col-md-2">
                                    <button type="button" class="btn btn-success btn-sm send_msg">
                                        发送
                                    button>
                                div>
                            div>

                            <div class="form-group row">
                                <label for="email" class="col-md-4 col-form-label text-md-right">短信验证码label>

                                <div class="col-md-6">
                                    <input type="text" class="form-control" name="code">
                                div>
                            div>

                            <div class="form-group row">
                                <label for="password"
                                       class="col-md-4 col-form-label text-md-right">密码:label>

                                <div class="col-md-6">
                                    <input id="password" type="password"
                                           class="form-control @error('password') is-invalid @enderror" name="password"
                                           required autocomplete="current-password">

                                    @error('password')
                                    <span class="invalid-feedback" role="alert">
                                        <strong>{{ $message }}strong>
                                    span>
                                    @enderror
                                div>
                            div>

                            <div class="form-group row">
                                <div class="col-md-6 offset-md-4">
                                    <div class="form-check">
                                        <input class="form-check-input" type="checkbox" name="remember"
                                               id="remember" {{ old('remember') ? 'checked' : '' }}>

                                        <label class="form-check-label" for="remember">
                                            记住我
                                        label>
                                    div>
                                div>
                            div>

                            <div class="form-group row mb-0">
                                <div class="col-md-8 offset-md-4">
                                    <button type="submit" class="btn btn-primary">
                                        {{ __('Login') }}
                                    button>

                                    @if (Route::has('password.request'))
                                        <a class="btn btn-link" href="{{ route('password.request') }}">
                                            忘记密码
                                        a>
                                    @endif
                                div>
                            div>
                        form>
                    div>
                div>
            div>
        div>
    div>
@endsection

<script src="{{ asset('js/jquery.min.js') }}">script>
<script src="{{ asset('js/common.js') }}">script>
<script>
    $(function () {
        $('.send_msg').click(function () {
            var mobile = $("#mobile").val();
            $.ajax({
                type: 'POST',
                url: '/send',
                data: {mobile: mobile},
                success:function(data){
                    if(data.status == 0){
                        alert(data.msg);
                    }
                }
            })
        })
    })
script>

页面显示效果如图:
Laravel6.0结合七牛云短信实现短信验证_第1张图片

LoginController.php 控制器中,重写登录,添加如下代码:

/**
 * 改成手机号登陆
 * Get the login username to be used by the controller.
 * @return string
 */
public function username()
{
    return 'mobile';
}

/***
 * 重写登录方法
 * @param Request $request
 * @return \Illuminate\Http\JsonResponse|\Illuminate\Http\Response|\Symfony\Component\HttpFoundation\Response
 * @throws \Illuminate\Validation\ValidationException
 */
public function login(Request $request)
{
    if ($request->code != session()->get('code')) {
        return response()->json(['msg' => '验证码填写错误']);
    }
    $this->validateLogin($request);

    if ($this->attemptLogin($request)) {
        return $this->sendLoginResponse($request);
    }

    $this->incrementLoginAttempts($request);

    return $this->sendFailedLoginResponse($request);
}

发送验证码进行测试,测试成功后,跳转指定页面即可。我这里只是写了一个案例,正式项目请自行集成。

以上是常规项目开发短信验证的使用方法。接下来给上 laravel + vue.js 实现发短信验证重置密码功能。

1、修改后端 send 方法中代码如下:

public function send(Request $request)
{
   $ak = "******";
   $sk = "******";
   $auth = new Auth($ak, $sk);
   $client = new \Qiniu\Sms\Sms($auth);

    //发送信息模块
    $template_id = "*****";
    $mobiles = array($request->mobile);

    if ($request->mobile == "") {
        return response()->json(['success' => false, 'message' => '请填写手机号!']);
       }
       if (!preg_match("/^1[34578]\d{9}$/", $request->mobile)) {
           return response()->json(['success' => false, 'message' => '手机号格式不正确!']);
       }

       $code = $this->GetRandStr(4);  // 随机生成短信验证码code,4代表验证码长度
       Cache::put('code', $code, 300);  // 把code存入缓存,5分钟内有效
       try {
           //发送短信
           $resp = $client->sendMessage($template_id, $mobiles, ['code' => $code]);
           if ($resp) {
               return response()->json(['success' => true, 'message' => '验证码已发送至您的手机!']);
           }
       } catch (\Exception $e) {
           echo "Error:", $e, "\n";
    }
}

api.php 中添加重设密码路由:

Route::put('reset_password', 'CustomerController@reset_password'); // 重设密码

在对应控制器中添加方法和代码如下:

/***
* 重设密码
*/
public function reset_password(Request $request)
{
    $mobile = $request->mobile;

    // 验证手机号是否存在
    $customer = Customer::where('mobile', $request->mobile)->first();
    if (!$customer) {
        return response()->json(['success' => false, 'message' => '手机号不存在!']);
    }

    $code = Cache::get('code');  //从缓存中获取code
    if (!$code) {
       return response()->json(['success' => false, 'message' => '请获取短信验证码!']);
    }
    if ($code != $request->code) {
        return response()->json(['success' => false, 'message' => '验证码填写错误!']);
    }

    $password = Hash::make($request->password);

    Customer::where('mobile', $mobile)->update(['password' => $password]);
    Cache::forget('code');  // 修改成功后清除缓存

    return response()->json(['success' => true, 'message' => '密码已重置']);
}

前端 (vue.js)

<template>
    <div>
        <div class="calendra">
            <div class="login-form">
                <h4>修改密码</h4>
                <form v-on:submit.prevent="onSubmit">
                    <div class="change_password_box">
                        <div class="change_password_tit">手机号</div>
                        <input placeholder="请输入手机号" v-model="customer.mobile">

                    </div>
                    <div class="change_password_box">
                        <div class="change_password_tit change_password_tit1">验证码</div>
                        <input class="change_password_yzm" placeholder="请输入验证码" v-model="customer.code">
                        <button type="button" class="tel_code" @click="getCode()">获取验证码</button>
                    </div>
                    <div class="change_password_box">
                        <div class="change_password_tit change_password_tit1">新密码</div>
                        <input class="change_password" placeholder="请输入新密码" v-model="customer.password">
                    </div>
                    <input class="change_password changeBtn" type="submit" value="修改密码">
                </form>
            </div>
        </div>
        <div class="clearfix"></div>
    </div>
</template>

<script>
    export default {
        data() {
            return {
                customer: {
                    mobile: '',
                    code: '',
                    password: ''
                }
            }
        },
        methods: {
            getCode() {
                this.axios.post(`/api/customer/send`, {mobile: this.customer.mobile}).then(res => {
                    if (res.data.success == false) {
                        this.$toast.center(res.data.message);
                        return false;
                    } else {
                        this.$toast.center(res.data.message);
                    }
                })
            },
            onSubmit() {
                const data = {
                    mobile: this.customer.mobile,
                    code: this.customer.code,
                    password: this.customer.password,
                }
                this.axios.put('/api/customer/reset_password', data)
                    .then(res => {
                        if (res.data.success == false) {
                            this.$toast.center(res.data.message);
                            return false;
                        } else {
                            this.$router.push({name: 'Login'})
                        }
                    })
            }
        }
    }
</script>

你可能感兴趣的:(vue.js,PHP,laravel,php,web,vue.js)