接口注册

api接

路由
<?php

use Illuminate\Support\Facades\Route;

/*
|--------------------------------------------------------------------------
| Web Routes
|--------------------------------------------------------------------------
|
| Here is where you can register web routes for your application. These
| routes are loaded by the RouteServiceProvider within a group which
| contains the "web" middleware group. Now create something great!
|
*/

Route::get('/', function () {
    return view('welcome');
});

Route::group(['namespace' => 'Api','middleware' =>['myapi']], function(){
    #登录接口
    Route::any('/user/login','UserController@login');
    #登录接口
    Route::any('/login2','UserController@login2');
    #发送短信验证码
    Route::any('/sendSms','PublicController@sendSms');
    #获取图片验证码的链接
    Route::any('/getImageCodeUrl','PublicController@getImageCodeUrl');
    #注册
    Route::any('/register','UserController@register');
});
#展示图片验证码,不需要加密解密
Route::any('/imageCode','Api\PublicController@imageCode');
#测试session
Route::any('/SessionTest','Api\PublicController@SessionTest');
apiCheck中间接
<?php

namespace App\Http\Middleware;

use Closure;
use Illuminate\Http\Request;

class ApiCheck
{
    /**
     * Handle an incoming request.
     *
     * @param  \Illuminate\Http\Request  $request
     * @param  \Closure  $next
     * @return mixed
     */
    public function handle(Request $request, Closure $next)
    {
        # 接受客户端传过来的data数据
        #因为客户端传递的数据是加密的,所以需要把数据解密回来
        if($data=$request->post('data')){
           #判断接口是否开启加密
            if(env('API_ENCRYPT')){
                #对称加密
                if(env('API_ENCRYPT_TYPE')==1)
                {
                   if(is_string($data)){
                       $decrypt_data = $this->AesDecrypt($data);
                   }else{
                       $decrypt_data =[];
                   }
                #非对称加密
                }else{
                    if(is_string($data)){
                        $decrypt_data = $this->RsaDecrypt($data);
                    }else{
                        $decrypt_data =[];
                    }
                }
            }else{
                $decrypt_data =$data;
            }
        }else{
            $decrypt_data =[];
        }
//        dd($decrypt_data);
        # 把接收的数据做一个替换
        $request -> replace((array)$decrypt_data);
        $response = $next($request);
        return $response;
    }

    /**
 * AES解密
 */
    private function AesDecrypt($data_str)
    {
        #加密
        $key=env('AES_KEY');
        $iv =env('AES_IV');

        #AES解密
        $decrypt_data=base64_decode($data_str);#反编码

        $origin_data=openssl_decrypt(
                    $decrypt_data,
                    'AES-256-CBC',
                    $key,
                    OPENSSL_RAW_DATA,
                    $iv
        );
//        var_dump($origin_data);exit;
        return json_decode($origin_data,true);

    }

    /**
     * RSA解密
     */
    private function RsaDecrypt($data_str)
    {
        #解密的方法
        $all = base64_decode($data_str);#反编码
        $j=1;
        $all_new='';
        while($sub_str=substr($all,($j -1)*128,128)){
            openssl_private_decrypt(
                $sub_str,
                $decrypt,
                file_get_contents(public_path() . '/private.key'),
                OPENSSL_PKCS1_PADDING
            );
            $all_new .=$decrypt;
            $j++;
        }
        return json_decode($all_new,true);
    }
}

UserController控制器
<?php

namespace App\Http\Controllers\Api;

use App\Http\Controllers\CommonController;
use App\models\MessageModel;
use App\models\UserModel;
use App\models\UserTokenModel;
use App\ParamMsg\Error;
use Illuminate\Http\Request;

/*用户相关的接口*/
class UserController extends CommonController
{

//    登录接口
/*
//    public function login(Request $request)
//    {
    /*       var_dump($request ->all());exit;

           $arr=[
               'status'=>200,
               'msg'=>'登录成功',
               'data'=>[]
           ];
           return $arr;*/
    public function login(Request $request)
    {
//        var_dump($request->all());exit;

        #接受用户的名字
        $user_name = $this -> checkParamIsEmpty('user_name');
        #接受密码
        $password = $this -> checkParamIsEmpty('password');
        #接受下登录的终端类型
        $tt = $this -> checkParamIsEmpty('tt');

        #去数据库查询用户是否存在
        $where=[
            ['user_name','=',$user_name]
        ];
        $user_obj=UserModel::where($where)->first();
//        var_dump($user_obj);exit;
        #判断用户是否存在
        if(empty($user_obj)){
            $this->showApiError('user_not_exists');
        }else{
            #检查用户的状态是否可以正常登陆
            $this->checkUserStatus($user_obj);

                #数据的密码是md5(密码+随机码)
                $user_input_password=md5($password.$user_obj->rand_code);

                #判断用户名和密码一致
                if($user_input_password==$user_obj -> password){
                    #成功返回用户信息 todo 这一块需要继续完善token相关功能
                    $user_info=$user_obj->toArray();
                    #获取用户id
                    $user_id=$user_info['user_id'];
                    #返回一个登录的令牌,后续调用接口的时候需要用到
                    $user_info['token']=$this->_creatUserToken($user_id,$tt);

                    #登录成功,重置用户的错误次数
                    $user_obj->error_count=null;
                    $user_obj->last_error_time=null;
                    $user_obj->save();
                    return $this->success($user_info);
                }else{
                    #给出对应提示信息
//                    $this->showApiError('user_password_not_match');
                    #为了防止暴力破解,1小时内,连续错误5次之后,把账号锁定2小时
                    $this->showApiError('',$this->userErrorCount($user_obj));
                }
        }
    }

/**
 * 记录用户的错误次数   1小时内,连续错误5次之后,把账号锁定2小时
 * @param UserModel $user_obj
 */
    private function userErrorCount(UserModel $user_obj){
        #获取当前时间
        $now=time();
        #包含错误信息的数组
        $msg_arr= Error::MSG;
        #若错误时间在二个小时 并且错误次数超过五次 提示现在是锁定状态
        if($now - $user_obj->last_error_time < 7200 && $user_obj->error_count >= 5){
            return sprintf($msg_arr['user_lock_two_hour'],date('H:i:s',$user_obj->last_error_time+7200));
        }
        #如果超过两个小时后 重新计算错误次数 变成 1  若未超过二小时就增加错误次数
        #一小时内错误5次 锁定账号
        if($now - $user_obj->last_error_time>=3600){
            $error_count=1;
        }else{
            $error_count = $user_obj->error_count+1;
        }

        #当错误次数为1  或 5时 需要记录 错误时间 便于 判断  (1为开头 5为结束)
        if($error_count==1 || $error_count==5){
            $user_obj->last_error_time = $now;
        }

        $user_obj->error_count =$error_count;

        #取出错误次数的提示信息  变成错误次数动态提示
        $error_msg = sprintf($msg_arr['password_error'],$error_count);

        #错误五次的时候,给出对应的提示
        if( $error_count==5){
            $error_msg= sprintf($msg_arr['user_lock_two_hour'],date('H:i:s',$user_obj->last_error_time+7200));
        }

        #判断数据库是否保存成功 成功给出 动态错误提示信息 失败 给出 密码错误提示信息
        if($user_obj->save()){
            return $error_msg;
        }else {
            return $msg_arr['user_password_not_match'];
        }
    }

    /*生成用户对应的token  默认有效期是1天*/
    protected function _creatUserToken($user_id,$tt=1)
    {
        #为了防止用户频繁的登录,每次都生成token
        $new =time();
        $where=[
            ['user_id','=',$user_id],
            ['ctime','>', $new - 60],
            ['login_type','=',$tt]
        ];
        #限制用户同一个终端一分钟只能登录三次 【登录成功】
        if(UserTokenModel::where($where)->count() >=3 ){
            $this->showApiError('many_login_success');
        }

        #把令牌写入数据库中
        $user_token_model=new UserTokenModel();
        $user_token_model->user_id = $user_id;

        #生成不重复令牌
        $user_token_model ->token=md5(uniqid());
        $user_token_model->expire=time()+86400;
        $user_token_model->login_type = $tt;
        $user_token_model->status =1;
        $user_token_model->ctime=time();

        #保存用户的令牌
        if($user_token_model -> save()){
            return $user_token_model-> token;
        }else{
            return false;
        }
    }

    /**
     * 注册
     */
    public function register(Request $request)
    {
        #短信验证码
        #手机号
        #密码
        $phone=$this->checkParamIsEmpty('phone');
        $password=$this->checkParamIsEmpty('password');
        $message_code=$this->checkParamIsEmpty('mcode');
        #取出改手机号对应的验证码

        $where=[
            ['phone','=',$phone]
        ];
        $m_obj=MessageModel::where($where)
            ->orderBy('id','desc')
            ->first();

        #判断该手机号是否存在
        if(empty($m_obj)){
            $this->showApiError('phone_message_empty');
        }

        #验证验证码是否正确
        if($m_obj->rand_code != $message_code){
            $this->showApiError('message_code_error');
        }
        #验证码只有2分钟的有效期
        $now=time();
        #说明超过2分钟
        if($now-$m_obj->ctime>120){
            $this->showApiError('message_code_expire');
        }
        #用户数据写入数据表
        #生成用户随机码
        $rand_code=rand();
        $user_model=new UserModel();

        $user_model->phone=$phone;
        $user_model->rand_code=$rand_code;
        $user_model->password=md5($password.$rand_code);
        $user_model->status=3;
        $user_model->ctime=time();
        if($user_model -> save() ){
              return $this->success();
        }else{
            $this->showApiError('register_fail');
        }
    }



    /*登录接口+前端使用js请求,格式是jsonp
public function login(Request $request)
{
    //接收传过来的get请求的数据
    $call=$request->get('callback');
    $arr=[
        'status'=>200,
        'msg'=>'',
        'data'=>[]
    ];
    echo $call.'('.json_encode($arr).')';
    exit;
}

public function login2(Request $request)
{
    $arr=[
        'status'=>200,
        'msg'=>'',
        'data'=>[]
    ];
    return $arr;
}*/


}

公共的
<?php
namespace App\Http\Controllers;

use App\models\UserModel;
use App\ParamMsg\Error;
use Illuminate\Http\Request;
use Illuminate\Routing\Controller;


/*API控制器的基类 所有API接口需要继承这个控制器*/
class CommonController extends Controller
{

    /*显示API的相关错误*/
    protected function showApiError($key,$msg='')
    {
        if($msg !=''){
            return $this->fail($msg);
        }else{
            #给出对应的提示
            return $this->fail( $this -> getErrorMsg ($key),100);
        }
    }
    //购买链接
https://market.aliyun.com/products/56928004/cmapi023305.html?spm=5176.10695662.1996646101.searchclickresult.4c1519fbrg125p#sku=yuncode1730500007
    /**
     * 发送短信的方法
     */
    public function sendAliSms($phone,$sms_code)
    {
        return true;exit;
        $host = "http://dingxin.market.alicloudapi.com";
        $path = "/dx/sendSms";
        $method = "POST";
        $appcode = "";//你自己的AppCode
        $headers = array();
        array_push($headers, "Authorization:APPCODE " . $appcode);
        $querys = "mobile=".$phone."&param=code%3A".$sms_code."&tpl_id=TP1711063";
        $bodys = "";
        $url = $host . $path . "?" . $querys;

        $curl=curl_init();
        curl_setopt($curl,CURLOPT_CUSTOMREQUEST,$method);
        curl_setopt($curl,CURLOPT_URL,$url);
        curl_setopt($curl,CURLOPT_HTTPHEADER,$headers);
        curl_setopt($curl,CURLOPT_FAILONERROR,false);
        curl_setopt($curl,CURLOPT_RETURNTRANSFER,true);
        curl_setopt($curl,CURLOPT_HEADER,false);
        if(1==strpos("$".$host,"https://")){
            curl_setopt($curl,CURLOPT_SSL_VERIFYPEER,false);
            curl_setopt($curl,CURLOPT_SSL_VERIFYHOST,false);
        }
        $curl_result=curl_exec($curl);
//        var_dump($curl_result);exit;
        $curl_arr=json_decode($curl_result,true);
//        var_dump(curl_exec($curl));

        if(!empty($curl_arr) && $curl_arr['return_code']=='00000'){
            return true;
        }else{
            return false;
        }

    }

    /**
     * 检查用户的状态
     * @return
     */
    protected function checkUserStatus($user_obj='',$user_id='')
    {
        if(!empty($user_obj) && $user_obj instanceof UserModel ){
            #判断用户状态  1待审核 2锁定 3正常 4已删除
            if($user_obj->status==1){
                $this->showApiError('user_not_check');
            }elseif(($user_obj->status==2)){
                $this->showApiError('user_is_lock');
            }elseif(($user_obj->status==4)){
                $this->showApiError('user_is_del');
            }
            #判断用户是否连续输错密码超过限制
            #获取当前时间
            $now=time();
            #包含错误信息的数组
            $msg_arr= Error::MSG;
            #若错误时间在二个小时 并且错误次数超过五次 提示现在是锁定状态
            if($now - $user_obj->last_error_time < 7200 && $user_obj->error_count >= 5){
                $this->showApiError('',
                    sprintf(
                    $msg_arr['user_lock_two_hour'],
                    date('H:i:s',$user_obj->last_error_time+7200)
                    )
                );
            }
        }
    }

    /*获取对应的错误提示信息*/
    public function getErrorMsg($key)
    {
        $error_all=Error::MSG;
        if(isset($error_all[$key])){
            $error_msg=$error_all[$key];
        }else{
            $error_msg='出现错误了';
        }
        return $error_msg;
    }

    /*检查参数是否为空*/
    protected function checkParamIsEmpty($key)
    {
        #接受客户端传递的参数
        $request_data=request()->all();
        #判断是否传递参数
        if(empty($request_data[$key])){
            #给出对应的提示
            return $this-> fail($this->getErrorMsg($key),1000);
        }else{
            #没有问题的时候,返回对应的值
            return $request_data[$key];
        }
    }

    /*失败的时候的提示信息*/
    protected function fail($msg='fail',$status=1,$data=[])
    {
        $arr=$this->jsonOutPut($status,$msg,$data);
//        return response($arr);
        echo json_encode($arr, JSON_UNESCAPED_UNICODE );
        exit;
    }

    /*成功的提示信息*/
    protected function success($data=[], $status=200,$msg='success')
    {
        return $this->jsonOutPut( $status,$msg,$data);
    }

    /*统一的数据返回*/
    private function jsonOutPut( $status,$msg,$data)
    {
        return[
            'status'=>$status,
            'msg'=>$msg,
            'data'=>$data
        ];
    }


}
<?php

namespace App\Http\Controllers\Api;

use App\Http\Controllers\CommonController;

use App\models\MessageModel;
use App\models\UserModel;
use Illuminate\Http\Request;

class PublicController extends CommonController
{
    /**
     * 测试Sessionid 传值
     * @param Request $request
     */
    public function SessionTest(Request $request)
    {
//        $request->session()->setId($request->get('sid'));
//        $request->session()->start();
//        $sid=$request->session()->getId();
////        var_dump($sid);
////        $request->session()->put(['user_name'=>'xiaoxiao']);
//        var_dump( $request->session()->get('user_name'));
    }

    /**
     * 发送短信验证码
     */
    public function sendSms(Request $request)
    {
        $phone = $this->checkParamIsEmpty('phone');
        $sid   = $this->checkParamIsEmpty('sid');
        $image_code = $this->checkParamIsEmpty('image_code');

        #发送短信验证码
        # 1、先判断手机号是否已经注册过
        $where=[
            ['phone','=',$phone]
        ];
        #2、判断用户是否存在
        if(UserModel::where($where)->count()>0){
            #给出对应的提示信息
            $this->showApiError('phone_already_exists');
        }
        #3、验证图片验证码是否正确
        $request->session()->setId($sid);
        $request->session()->start();
        $code=$request->session()->get('image_code');

        #4、验证码不正确给出对应提示信息
//        if($image_code !='8888'&& $code !=$image_code)
        if($code !=$image_code)
        {
            $this->showApiError('image_code_error');
        }


        #发送短信验证码
        #限制短信发送的频率【同一个1天最多发送10条,每条1分钟的可以发送一次】
        #限制1天最多发送10条
        $today_start=strtotime(date('Y-m-d'));
        $today_end=$today_start+86400;

        $where=[
            ['phone','=',$phone],
            ['ctime','>=',$today_start],
            ['ctime','<=',$today_end]
        ];
        #一天内超过10条不让继续发送
        if(MessageModel::where($where)->count() >=10){
            $this->showApiError('send_more_message');
        }
        #限制1分钟才能继续发送
        $where=[
            ['phone','=',$phone],
            ['ctime','>=',time()-60],
        ];
        #每次发送时间超过1分钟
        if(MessageModel::where($where)->count()>=1){
            $this->showApiError('message_one_minute_limit');
        }
        #先调用短信发送接口
        $sms_code=rand(100000,999999);
        #调用短信发送接口
        if($this->sendAliSms($phone,$sms_code))
        {
            $model=new MessageModel();
            $model->phone=$phone;
            $model->rand_code=$sms_code;
            #1注册 2找回密码
            $model->message_type=1;
            $model->message_content=$sms_code;
            $model->is_send=1;
            $model->status=1;
            $model->ctime = time();
            if($model->save()){
                return $this->success();
            }else{
                $this->showApiError('message_send_error');
            }
        }else{
            $this->showApiError('message_send_error2');
        }
    }


    /**
     * 获取图片验证码的url
     */
    public function getImageCodeUrl(Request $request)
    {
        $request->session()->start();
        $sid=$request->session()->getId();
//        var_dump($sid);exit;
        $domain=str_replace(
            $request->path(),
            '',
            $request->url()
        );
        $image_code_url=$domain.'imageCode?sid='.$sid;

        $api_return_arr=[
            'image_url'=>$image_code_url,
            'sid'=>$sid
        ];

        return $this->success($api_return_arr);
    }

    /**
     * 图片验证码
     * @param Request $request
     */
    public function imageCode(Request $request)
    {
//        dd($request->all());
      $sid=$request->get('sid');
//        var_dump($sid);exit;
        if(empty($sid)){
            $this->showApiError('','缺少必须参数!');
        }

        #要在画板上写文字
        $text= ''.rand(1000,9999);

        #指定当前的会话id
        $request->session()->setId($sid);
        $request->session()->start();
        #开启session
        $request->session()->put('image_code',$text);

        #输出图片最后要exit 这个地方收到调用一下save
        $request->session()->save();

        #告诉浏览器要输出对是png格式对图片
        header('Content-Type:image/png');

        #创建一个画布
        $im=imagecreatetruecolor(100,30);

        #创建几个颜色
        $white=imagecolorallocate($im,255,255,255);
        $black=imagecolorallocate($im,0,0,0);

        #画布填充颜色
        imagefilledrectangle($im,0,0,339,29,$white);

        #设置字体文件
        $font=public_path().'/Verdana.ttf';

        #画布上写字
        $i=0;
        while($i<strlen($text)){
            if($i==0){
                imagettftext($im,20,rand(-15,30),$i * 25,24,$black,$font,$text[$i]);
            }else{
                imagettftext($im,20,rand(-15,30),$i * 25,24,$black,$font,$text[$i]);
            }
            $i++;
        }
        #输出图片
        imagepng($im);
        imagedestroy($im);
        #exit不能省掉
        exit;

    }




}
错误提示
<?php
namespace App\ParamMsg;

/*接口相关的错误提示信息*/
class Error
{
    #接口相关的错误提示信息
    const MSG=[
        #账户名为空的时候的提示信息
        'user_name'=>'用户名不能为空',
        #密码不为空的时候的提示信息
        'password'=>'你还没有输入密码呢!',
        #用户不存在的提示信息
        'user_not_exists'=>'你要登陆的账号没有找到',
        'user_not_check' =>'你的账号还没有审核通过',
        'user_is_lock'   =>'你的账号被锁定了,请联系客服给您解锁',
        'user_is_del'    =>'你要登陆的账号不存在',
        'user_password_not_match'=>'账号密码不一致,请核对后,再次尝试',
        'tt'=>'请选择你要登录的终端类型',
        'many_login_success'=>'登录太过频繁,请等一会,再次尝试',
        'password_error'=>'你的账号已经输错%s次,错误5次账号会被锁定2小时',
        'user_lock_two_hour'=>'你的账号已经被锁定,请在%s点后在次尝试!',
        'phone'=>'请输入你的手机号',
        'sid'=>'验证码错误!',
        'image_code'=>'请输入图片验证码',
        'phone_already_exists'=>'手机号已经存在了',
        'image_code_error'=>'图片验证码输入错误',
        'send_more_message'=>'一天最多发送10条',
        'message_one_minute_limit'=>'短信发送太过频繁',
        'message_send_error'=>'短信发送失败,MYSQL插入失败',
        'message_send_error2'=>'短信发送失败,请检查!',
        'mcode'=>'短信验证码不能为空',
        'message_code_expire'=>'短信验证码已过期(2分钟)',
        'message_code_error'=>'短信验证码不正确',
        'register_fail'=>'注册失败,请重试!',
        'phone_message_empty'=>'该手机号不存在,请确认后,在重试!',
    ];

}
env
APP_NAME=Laravel
APP_ENV=local
APP_KEY=base64:259fA+3F5jGtyk0vv6efGwFIC6kOx+M2wk7Ya9Z6N64=
APP_DEBUG=true
APP_URL=http://localhost

LOG_CHANNEL=stack

DB_CONNECTION=mysql
DB_HOST=127.0.0.1
DB_PORT=3306
DB_DATABASE=api_project
DB_USERNAME=root
DB_PASSWORD=lidanyang

BROADCAST_DRIVER=log
CACHE_DRIVER=file
QUEUE_CONNECTION=sync
SESSION_DRIVER=file
SESSION_LIFETIME=120

REDIS_HOST=127.0.0.1
REDIS_PASSWORD=null
REDIS_PORT=6379

MAIL_MAILER=smtp
MAIL_HOST=smtp.mailtrap.io
MAIL_PORT=2525
MAIL_USERNAME=null
MAIL_PASSWORD=null
MAIL_ENCRYPTION=null
MAIL_FROM_ADDRESS=null
MAIL_FROM_NAME="${APP_NAME}"

AWS_ACCESS_KEY_ID=
AWS_SECRET_ACCESS_KEY=
AWS_DEFAULT_REGION=us-east-1
AWS_BUCKET=

PUSHER_APP_ID=
PUSHER_APP_KEY=
PUSHER_APP_SECRET=
PUSHER_APP_CLUSTER=mt1

MIX_PUSHER_APP_KEY="${PUSHER_APP_KEY}"
MIX_PUSHER_APP_CLUSTER="${PUSHER_APP_CLUSTER}"

AES_KEY="1908phpA"
AES_IV="1213515561561512"

#API是否开启加密 0关闭加密1开启加密
API_ENCRYPT=1
#1对应加密2非对称加密
API_ENCRYPT_TYPE=2
model
1<?php

namespace App\models;

use Illuminate\Database\Eloquent\Model;

class MessageModel extends Model
{
    protected  $table='exam_message';
    protected $primaryKey='id';
    public $timestamps=false;
    protected  $guarded=[];
}
2<?php

namespace App\models;

use Illuminate\Database\Eloquent\Model;

class UserModel extends Model
{
    protected  $table='exam_user';
    protected $primaryKey='user_id';
    public $timestamps=false;
    protected  $guarded=[];
}
3<?php

namespace App\models;

use Illuminate\Database\Eloquent\Model;

class UserTokenModel extends Model
{
    //表名
    protected  $table='exam_user_token';
    //主见id
    protected $primaryKey='id';
    //关闭时间补全
    public $timestamps=false;

    protected  $guarded=[];
}

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

发布了3 篇原创文章 · 获赞 0 · 访问量 16

猜你喜欢

转载自blog.csdn.net/weixin_47124571/article/details/105630635