zoukankan      html  css  js  c++  java
  • 【小程序+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)
                }
              }
            })
          }
        })

    三: 测试结果: 

  • 相关阅读:
    rc.local文件
    mysql 常用语句模板
    gradle使用
    Elasticsearch 聚合
    华盛顿大学 Programming Languages
    802.11基础
    802.11简单认证过程
    网络诊断错误归类
    802.1X基础
    终端管理软件tmux
  • 原文地址:https://www.cnblogs.com/richerdyoung/p/8275067.html
Copyright © 2011-2022 走看看