微信小程序+tp6 授权登录 中间键token验证 接口恶意请求

静默登录

app.js 全局配置里 

App({
  onLaunch() {

    // 展示本地存储能力

    const logs = wx.getStorageSync('logs') || []

    logs.unshift(Date.now())
    wx.setStorageSync('logs', logs)

    // 登录
    wx.login({

      success: res => {

        wx.request({

          url: 'url',

          method: "POST",

          data: {

            code: res.code

          },

          success: (result) => {

            console.log(result);

            wx.setStorage({

              key: 'open_id',

              data: result.data.data.open_id

            })

            wx.setStorage({

              key: 'token',

              data: result.data.data.token

            })
          },
        })
        // 发送 res.code 到后台换取 openId, sessionKey, unionId
      }
    })
  },
  globalData: {
    userInfo: null
  }
})

封装curl  config

return [
    "url"=>"https://api.weixin.qq.com/sns/jscode2session?appid=%s&secret=%s&js_code=%s&grant_type=authorization_code",
    'AppID'=>'',//自己的微信小程序appsecret
    "AppSecret"=>'',//自己的微信小程序appsecret
];

 

 

封装curl

function curlGet($url){
    $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);
    return $output;
}

 tp6 控制器

public function login(Request $request){
        //获取code码

        $code = $request->post('code'); //var_dump($code);die();

        //获取微信授权url

        $url = sprintf(config('wx.url'),config('wx.AppID'),config('wx.AppSecret'),$code);

        //获取openid

        $data = json_decode(file_get_contents($url));

        $data = (array)$data;

        //进行查询数据库里面是否有该用户,如果没有,则进行新增

        $user = User::where('open_id',$data['openid'])->find();

        //如果没有用户进行创建

        if (empty($user)){

            $user = User::insert([

                'open_id'=>$data['openid'],

                'session_key'=>$data['session_key'],

            ]);
        }

        //生成token,保存用户登录状态

        $token = (new \app\home\service\JWT())->getToken($user->id);

        return success(['token'=>$token,'open_id'=>$data['openid']]);
    }

tp6 中间件

//中间件验证token 和 接口并发 恶意请求问题的解决   

public function handle($request, \Closure $next)
    {
        $token = $request->header('token');
        try{
            $userId = JWT::getUserId($token);
            if (!$userId){
                return fail('token不存在');
            }
            $requestLimit = Cache::store('redis')->get($request->ip() . '_' . $userId);
            if ($requestLimit) {

                // 存在判断当前数量是否大于20次
                if ($requestLimit > 20) {

                    throw new Exception('操作过快');

                } else {

                    // 当前操作数量不大于20次则自增1次
                    Cache::store('redis')->inc($request->ip() . '_' . $userId,1);

                }
            } else {

                // 不存在记录当前ip下用户操作次数,有效期1分钟内
                Cache::store('redis')->set($request->ip() . '_' . $userId,1,60);

            }
        }catch (\Exception $e){
            return fail('内部错误');
        }
        return $next($request);
    }

安装 JWT

composer require lcobucci/jwt 3.3

JWT 封装

<?php
/**
 * Created by PhpStorm.
 * User: HentHao
 * Date: 2022/2/19
 * Time: 9:30
 */

namespace app\home\service;

use Lcobucci\JWT\Signer\Hmac\Sha256;
use Lcobucci\JWT\Builder;
use Lcobucci\JWT\Parser;
use Lcobucci\JWT\ValidationData;

class JWT
{
    private static $_config = [
        'audience' => 'http://www.pyg.com',//接收人
        'id' => '3f2g57a92aa',//token的唯一标识,这里只是一个简单示例
        'sign' => 'pinyougou',//签名密钥
        'issuer' => 'http://adminapi.pyg.com',//签发人
        'expire' => 3600 * 24 //有效期
    ];

    //生成token
    public static function getToken($user_id)
    {
        //签名对象

        $signer = new Sha256();

        //获取当前时间戳

        $time = time();

        //设置签发人、接收人、唯一标识、签发时间、立即生效、过期时间、用户id、签名

        $token = (new Builder())->issuedBy(self::$_config['issuer'])

            ->canOnlyBeUsedBy(self::$_config['audience'])

            ->identifiedBy(self::$_config['id'], true)

            ->issuedAt($time)

            ->canOnlyBeUsedAfter($time - 1)

            ->expiresAt($time + self::$_config['expire'])

            ->with('user_id', $user_id)

            ->sign($signer, self::$_config['sign'])

            ->getToken();

        return (string)$token;
    }

    //从请求信息中获取token令牌
    public static function getRequestToken()
    {
        if (empty($_SERVER['HTTP_AUTHORIZATION'])) {
            return false;
        }

        $header = $_SERVER['HTTP_AUTHORIZATION'];

        $method = 'bearer';

        //去除token中可能存在的bearer标识
        return trim(str_ireplace($method, '', $header));
    }

    //从token中获取用户id (包含token的校验)
    public static function getUserId($token = null)
    {
        $user_id = null;

        $token = empty($token) ? self::getRequestToken() : $token;

        if (!empty($token)) {
            //为了注销token 加以下if判断代码
            $delete_token = cache('delete_token') ?: [];

            if (in_array($token, $delete_token)) {

                //token已被删除(注销)
                return $user_id;
            }

            $token = (new Parser())->parse((string)$token);

            //验证token
            $data = new ValidationData();

            $data->setIssuer(self::$_config['issuer']);//验证的签发人

            $data->setAudience(self::$_config['audience']);//验证的接收人

            $data->setId(self::$_config['id']);//验证token标识

            if (!$token->validate($data)) {
                //token验证失败
                return $user_id;
            }

            //验证签名
            $signer = new Sha256();

            if (!$token->verify($signer, self::$_config['sign'])) {
                //签名验证失败
                return $user_id;
            }

            //从token中获取用户id

            $user_id = $token->getClaim('user_id');
        }

        return $user_id;
    }
}

中间件获取token  header获取token

 wx.request({
      url: 'url',

      header: {

        'context-type':'application/json',

        'token': wx.getStorageSync('token')//后端能够获取token
      },
      success(res){

        console.log(res);

        let hotel = res.data.data;

        //渲染数据
        _this.setData({
          hotel
        })

      }
    })

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值