laravel8 实现小程序颁发token、注册登录以及单接口频次限制

创建路由

//颁发token
Route::post('login',[\App\Http\Controllers\Users::class,'index']);
//登录
Route::prefix('user')->group(function (){
    Route::post('wxLogin',[\App\Http\Controllers\Users::class,'store']);
});

微信小程序封装wx.request

// 定义连接通用地址 (域名)
const pubUrl = "http://www.域名.com/index.php/api/"
// 定义请求
const http = (url,method,data,header) =>{
    return new Promise((resolve,reject) => {
        wx.request({
            url:pubUrl+url,
            method:method || 'get',
            data:data || {},
            header: header || {},
             success(request) {
                if (request.statusCode == 200) {
                resolve(request.data)
                } else {
                reject(request.data.msg)
                }
                }
        })
    }
    )}

    // 导出
    export default http

微信小程序调用

import http from "./common/common.js"
App({
  onLaunch() {
    // 判断token是否存在
    var token = wx.getStorageSync('token')
    if (token) {
      //  判断是否登录过
      var id = wx.getStorageSync('id')
      // 登录请求
      if (id == "") {
        wx.login({
          timeout: 2000,
          success: ({ code }) => {
            // code有效期5分钟
            // 发起请求
            let header = { 'Authorization': 'Bearer' + " " + token }
            // 实例化
            var promise = new Promise(function (resolve) {
              // 调用请求
              resolve(http("user/wxLogin", 'POST', { code }, header));
            });
            // 取出请求里的值,存用户id
            promise.then(function (value) {
              wx.setStorageSync('id', value.data)
            }).catch(function (error) {
              console.error(error);
            });
          }
        })
      }
    } else {
      // 实例化
      var promise = new Promise(function (resolve) {
        let data = [{ username: 'admin', password: 'admin' }];
        // 调用请求
        resolve(http("login", 'POST', data));
      });
      // 取出请求里的值
      promise.then(function (value) {
        wx.setStorageSync('token', value.data.token)
      }).catch(function (error) {
        console.error(error);
      });
    }
  }
})

laravel8获取token

php
public function index(Request $request)
{
    $bool = auth()->guard('apiweb')->attempt($request->post(0));
    if ($bool) {
        $userModel = auth()->guard('apiweb')->user();
        $token = $userModel->createToken('api')->accessToken;
        $data = [
            'expire' => 7200,
            'token' => $token
        ];
        return response(['data' => $data, 'code' => 200, 'msg' => 'token成功']);
    } else {
        return response(['data' => "", 'code' => 400, 'msg' => 'token失败']);
    }

}

public function store(Request $request)
{
    $code = $request->post('code');
    $appid = "";
    $appSecret = "";
    $url = "https://api.weixin.qq.com/sns/jscode2session?appid={$appid}&secret={$appSecret}&js_code={$code}&grant_type=authorization_code";
    $headerArray = array("Content-type:application/json;", "Accept:application/json");
    $ch = curl_init();
    curl_setopt($ch, CURLOPT_URL, $url);
    curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, FALSE);
    curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, FALSE);
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
    curl_setopt($ch, CURLOPT_HTTPHEADER, $headerArray);
    $output = curl_exec($ch);
    curl_close($ch);
    $output = json_decode($output, true);
    $openid = $output['openid'];
    //查看表里openid是否存在
    $res = Admins::selectData($openid);
    if (count($res) == 0) {
        $arr = ['nikename' => "微信用户" . rand(1111, 33333), 'openid' => $openid];
        //添加数据
        $result = Admins::addData($arr);
        if (!$result) {
            return response(['code' => 400, 'msg' => "注册失败"]);
        }
    }
    //将用户id返回
    $id = Admins::selectData($openid);
    return response(['code' => 200, 'msg' => "注册成功", 'data' => $id[0]['id']]);
}

安装 Redis

composer require predis/predis

文档:Redis《Laravel 8 中文文档》

//写入中间件,然后进行拦截
//判断 key 是否存在,存在则加一 increment,不存在则设置key 过期时间
        $id = 1;
        $url = $request->getPathInfo();

        // 判断key是否存在
        $check = Cache::store('redis')->has('qps_' . $id . $url);
        if ($check){
            // +1
            Cache::store('redis')->increment('qps_' . $id . $url);
            echo   $count = Cache::store('redis')->get('qps_' . $id . $url);
            // 限制每分钟10次
            if($count > 5){
                echo '当前id请求频率过高';
                exit;
            }
        } else {
            Cache::store('redis')->set('qps_' . $id . $url, 1,60);//初始值1
        }
        return $next($request);
本作品采用《CC 协议》,转载必须注明作者和本文链接
《L04 微信小程序从零到发布》
从小程序个人账户申请开始,带你一步步进行开发一个微信小程序,直到提交微信控制台上线发布。
《L02 从零构建论坛系统》
以构建论坛项目 LaraBBS 为线索,展开对 Laravel 框架的全面学习。应用程序架构思路贴近 Laravel 框架的设计哲学。
讨论数量: 2

接口频次

public function handle(Request $request, Closure $next)
    {
        //假如uid=1
        $id=$request->post('a_id');

        $key=$request->ip().'_'.$request->getPathInfo().'_'.$id;

        // 判断key是否存在
        $check=Cache::store('redis')->has($key);

        if ($check){
            Cache::store('redis')->increment($key);
            $count=Cache::store('redis')->get($key);
            if ($count>2){
                return response(['msg'=>"次数过多"]);
            }
        }else{
            Cache::store('redis')->set($key,1,60);
        }

        return $next($request);
    }
2年前 评论

禁用

 <form catchsubmit="formSubmit">
 <button type="primary" disabled="{{nodes}}" form-type="submit">提交信息</button>
 </form>
 formSubmit(e){
let content=e.detail.value.content
    // 商品id
    var g_id = wx.getStorageSync('g_id')
    // 用户id
    var a_id = wx.getStorageSync('id')
    let that = this;
    // 判断token是否存在
    var token = wx.getStorageSync('token')
    let header = { 'Authorization': 'Bearer' + " " + token }
  // 实例化
  var promise = new Promise(function (resolve) {
    // 调用请求
    resolve(http("goods/goodsComment", 'post', {a_id,g_id,content}, header));
  });
  // 取出请求里的值
  promise.then(function (res) {
    console.log(res)
    if(res.msg=="次数过多"){
      that.setData({nodes:"nodes"})
    }
  }).catch(function (error) {
    console.error(error);
  });
  },
2年前 评论

讨论应以学习和精进为目的。请勿发布不友善或者负能量的内容,与人为善,比聪明更重要!