【小程序+thinkphp5】 用户登陆,返回第三方session3rd

服务器环境: centos7   php7.0

准备工作: 

  • 注册小程序,并获取 appid 、appsecret
  • 下载微信解密算法sdk : https://mp.weixin.qq.com/debug/wxadoc/dev/api/signature.html
  • https 的域名。需要在小程序后台服务器域名那配置

   

代码实现

 一 、 thinkphp5 

1  /extend/wxdev   把下载的加密算法放进去 

     坑1 : 微信下载的文件编码为: UTF-8-bootom  ,注意自己转换一下(不会的直接新建文件。把代码复制进去)

     坑2 :wxBizDataCrypt.php文件中  构造函数, 微信官方使用的和类名一致, php 高版本不支持(亲测: PHP5.6支持, PHP7.0 不支持)。请改为: __construct 

2  新建微信配置文件: /application/extra/wechat.php   

<?php
// +----------------------------------------------------------------------
// | Desc: 微信配置文件
// +----------------------------------------------------------------------
// | Author: 依然范儿特西
// +----------------------------------------------------------------------

return [

    //微信小程序ID
    "wx_appid"=>"",
    //微信小程序密钥
    'wx_appsecret'=>"",
    //微信接口域名
    "wx_request_url"=>"https://api.weixin.qq.com/sns/jscode2session",

];

3   /application/common.php    

     
    /** 
     * 发送HTTP请求方法 
     * @param string $url  请求URL 
     * @param array $params 请求参数 
     * @param string $method 请求方法GET/POST 
     * @return array $data  响应数据 
     */
    function http_send($url, $params, $method = 'GET', $header = array(), $multi = false){ 
        $opts = array( 
        CURLOPT_TIMEOUT    => 30, 
        CURLOPT_RETURNTRANSFER => 1, 
        CURLOPT_SSL_VERIFYPEER => false, 
        CURLOPT_SSL_VERIFYHOST => false, 
        CURLOPT_HTTPHEADER   => $header 
        ); 
        /* 根据请求类型设置特定参数 */
        switch(strtoupper($method)){ 
        case 'GET': 
            $opts[CURLOPT_URL] = $url . '?' . http_build_query($params); 
            break; 
        case 'POST': 
            //判断是否传输文件 
            $params = $multi ? $params : http_build_query($params); 
            $opts[CURLOPT_URL] = $url; 
            $opts[CURLOPT_POST] = 1; 
            $opts[CURLOPT_POSTFIELDS] = $params; 
            break; 
        default: 
            throw new Exception('不支持的请求方式!'); 
        } 
        /* 初始化并执行curl请求 */
        $ch = curl_init(); 
        curl_setopt_array($ch, $opts); 
        $data = curl_exec($ch); 
        $error = curl_error($ch); 
        curl_close($ch); 
        if($error) throw new Exception('请求发生错误:' . $error); 
        return $data; 
    } 

4 控制器代码:  /application/wechat/controller/Wx.php

<?php
namespace appwechatcontroller;
use  thinkController;   //使用控制器
use  thinkDb;  //使用数据库操作
use  thinkRequest;
use  thinkconfig;
use WxdevWXBizDataCrypt; 
/*
* 微信模块
 */
class Wxrun  extends Base{
    function __construct(){
        parent::__construct();
    }
    
    public function index(){
        // 指定json数据输出
        return json(['code'=>110,'message'=>"Power By 研发中心","result"=>null]);
    }
    
    //用户登陆
    public  function user_login(){
      $APPID = config::get("wechat.wx_appid"); 
      $AppSecret = config::get("wechat.wx_appsecret"); 
      $wx_request_url = config::get("wechat.wx_request_url"); 
      $code = input("code");
      $param = array( 
        'appid' => $APPID, 
        'secret' => $AppSecret, 
        'js_code' => $code, 
        'grant_type' => 'authorization_code'
      ); 
       // 一个使用curl实现的get方法请求
      $arr = http_send($wx_request_url, $param, 'post'); 
      $arr = json_decode($arr,true);
      if(isset($arr['errcode']) && !empty($arr['errcode'])){
          return json(['code'=>'2','message'=>$arr['errmsg'],"result"=>null]);
      }
      $openid = $arr['openid'];
      $session_key = $arr['session_key'];

      // 数据签名校验
      $signature = input("signature");
      $signature2 = sha1($_GET['rawData'].$session_key);  //别用框架自带的input,会过滤掉必要的数据
      if ($signature != $signature2) {
          $msg = "shibai 1";
          return json(['code'=>'2','message'=>'获取失败',"result"=>$msg]);
      }

      //开发者如需要获取敏感数据,需要对接口返回的加密数据( encryptedData )进行对称解密
      $encryptedData = $_GET['encryptedData'];
      $iv = $_GET['iv'];
      include_once (EXTEND_PATH. 'Wxdev/wxBizDataCrypt.php');
      $pc = new WXBizDataCrypt($APPID, $session_key);
      $errCode = $pc->decryptData($encryptedData, $iv, $data);  //其中$data包含用户的所有数据
      if ($errCode != 0) {
          return json(['code'=>'2','message'=>'获取失败',"result"=>null]);
      }
      /****** */
      //写自己的逻辑: 操作数据库等操作
       /****** */
      //生成第三方3rd_session
      $session3rd  = null;
      $strPol = "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyz";
      $max = strlen($strPol)-1;
      for($i=0;$i<16;$i++){
          $session3rd .=$strPol[rand(0,$max)];
      }
      return json(['code'=>'1','message'=>'获取成功',"result"=>$session3rd]);

    }    
   

}

二 、 小程序代码:

 直接在 app.js 编写

// 登录
    wx.login({
      success: res => {
        // 发送 res.code 到后台换取 openId, sessionKey, unionId
        var code = res.code;
        wx.getUserInfo({
          success: res => {
            // 可以将 res 发送给后台解码出 unionId
            this.globalData.userInfo = res.userInfo
            var rawData = res.rawData;
            var signature = res.signature;
            var encryptedData = res.encryptedData;
            var iv = res.iv;
            wx.request({
              url: 'https://www.test.com/wechat/wx/user_login',
              data: {
                "code": code,
                "rawData": rawData,
                "signature": signature,
                'iv': iv,
                'encryptedData': encryptedData
              },
              success: function (info) {
                console.log(info);
              }
            })
            // 由于 getUserInfo 是网络请求,可能会在 Page.onLoad 之后才返回
            // 所以此处加入 callback 以防止这种情况
            if (this.userInfoReadyCallback) {
              this.userInfoReadyCallback(res)
            }
          }
        })
      }
    })

三: 测试结果: 

原文地址:https://www.cnblogs.com/richerdyoung/p/8275067.html