ThinkPHP5-微信小程序获取用户授权登录信息

因为最近在用TP5开发小程序,所以就上网搜索了一下TP框架对应的微信小程序获取授权信息的依赖,但是结果不太理想,于是就借鉴了laravel的iwanli/wxxcx依赖,自己手动写了一个TP5的获取信息接口,下面分享一下具体的实现流程。

1.梳理

首先要知道的是,小程序开发中,微信小程序授权时后台会获取的参数:

  • encryptedData:加密后的用户信息
  • code:登录凭证码
  • iv:偏移向量,在解密是要用到的

这三个参数是通过小程序前端发送到后台的。

之后需要去微信小程序官方文档里面下载解密 sdk

下载完毕之后,解压并放入TP5项目的extend文件夹里面。

2.实现流程

首先在控制器中引用,以本人代码为例。

.
.
.
//引用解密组件
use wxxcx\wxBizDataCrypt;

.
.
.
    public function demo()
    {
        // 前台参数
        $encryptedData = input('get.encryptedData');
        $code          = input('get.code');
        $iv            = input('get.iv');

        // 小程序 appid 和 appsecret
        $appid     = 'wx4f4bc4dec97d474b';
        $appsecret = '#################';

        // step1
        // 通过 code 用 curl 向腾讯服务器发送请求获取 session_key
        $session_key = $this->sendCode($appid, $appsecret, $code);

        // step2
        // 用过 session_key 用 sdk 获得用户信息
        $save = [];

        // 相关参数为空判断
        if (empty($session_key) || empty($encryptedData) || empty($iv)) {
            $msg = "信息不全";
            return $this->ApiSuccess($save, $msg);
        }

        //进行解密
        $userinfo = $this->getUserInfo($encryptedData, $iv, $session_key, $appid);

        // 解密成功判断
        if (isset($userinfo['code']) && 10001 == $userinfo['code']) {
            $msg = "请重试"; // 用户不应看到程序细节
            return $this->ApiSuccess($save, $msg);
        }

        session('myinfo', $userinfo);
        $save['openid']    = &$userinfo['openId'];
        $save['uname']     = &$userinfo['nickName'];
        $save['unex']      = &$userinfo['gender'];
        $save['address']   = &$userinfo['city'];
        $save['avatarUrl'] = &$userinfo['avatarUrl'];
        $save['time']      = time();
        $map['openid']     = &$userinfo['openId'];

        $msg = "获取成功";

        //返回用户信息
        return $this->ApiSuccess($save, $msg);

    }

    //获取微信用户信息
    private function sendCode($appid, $appsecret, $code)
    {
        // 拼接请求地址
        $url = 'https://api.weixin.qq.com/sns/jscode2session?appid='
            . $appid . '&secret=' . $appsecret . '&js_code='
            . $code . '&grant_type=authorization_code';

        $arr = $this->vegt($url);
        $arr = json_decode($arr, true);

        return $arr['session_key'];
    }

    // curl 封装
    private function vegt($url)
    {
        $info = curl_init();
        curl_setopt($info, CURLOPT_RETURNTRANSFER, true);
        curl_setopt($info, CURLOPT_HEADER, 0);
        curl_setopt($info, CURLOPT_NOBODY, 0);
        curl_setopt($info, CURLOPT_SSL_VERIFYPEER, false);
        curl_setopt($info, CURLOPT_SSL_VERIFYHOST, false);
        curl_setopt($info, CURLOPT_URL, $url);
        $output = curl_exec($info);
        curl_close($info);
        return $output;
    }

    //信息解密
    private function getUserInfo($encryptedData, $iv, $session_key, $APPID)
    {
        //进行解密
        $pc         = new WXBizDataCrypt($APPID, $session_key);
        $decodeData = "";
        $errCode    = $pc->decryptData($encryptedData, $iv, $decodeData);
        //判断解密是否成功
        if ($errCode != 0) {
            return [
                'code'    => 10001,
                'message' => 'encryptedData 解密失败',
            ];
        }
        //返回解密数据
        return json_decode($decodeData, true);
    }
.
.
.

以上就是TP5获取微信小程序授权用户信息的实现流程。

可以将代码中vegt方法转到公共函数库中

sendCodegetUserInfo可以进行抽象、再次改进,实现功能分离。

以后如果有钉钉小程序,百度小程序等等用户信息获取,都可以用

本作品采用《CC 协议》,转载必须注明作者和本文链接
lanffff
讨论数量: 5
bing8u

你这代码质量太low……
解决方案:用composer 安装 GuzzleHttp\Client;
不管什么框架,写的思路、实现过程都差不多,是编写代码渣不渣的问题。

<?php

namespace App\Http\Controllers\Api;

use App\Http\Controllers\Controller;
use GuzzleHttp\Client;
use Illuminate\Http\Request;

class MiniAppController extends Controller
{
    public function login(Request $request)
    {
        $data = $request->validate(['js_code' => 'required']);

        $response = (new Client)->get('https://api.weixin.qq.com/sns/jscode2session', [
            'query' => [
                'appid' => config('pay.wechat.miniapp_id'),
                'secret' => config('pay.wechat.miniapp_key'),
                'js_code' => data_get($data, 'js_code'),
                'grant_type' => 'authorization_code',
            ]
        ]);

        return json_decode((string)$response->getBody(), true);
    }

    public function token()
    {
        $response = (new Client)->get('https://api.weixin.qq.com/cgi-bin/token', [
            'query' => [
                'appid' => config('pay.wechat.miniapp_id'),
                'secret' => config('pay.wechat.miniapp_key'),
                'grant_type' => 'client_credential',
            ]
        ]);

        return json_decode((string)$response->getBody(), true);
    }
}
4年前 评论
lanffff (楼主) 4年前
Tinywan 4年前
bing8u

你这代码质量太low……
解决方案:用composer 安装 GuzzleHttp\Client;
不管什么框架,写的思路、实现过程都差不多,是编写代码渣不渣的问题。

<?php

namespace App\Http\Controllers\Api;

use App\Http\Controllers\Controller;
use GuzzleHttp\Client;
use Illuminate\Http\Request;

class MiniAppController extends Controller
{
    public function login(Request $request)
    {
        $data = $request->validate(['js_code' => 'required']);

        $response = (new Client)->get('https://api.weixin.qq.com/sns/jscode2session', [
            'query' => [
                'appid' => config('pay.wechat.miniapp_id'),
                'secret' => config('pay.wechat.miniapp_key'),
                'js_code' => data_get($data, 'js_code'),
                'grant_type' => 'authorization_code',
            ]
        ]);

        return json_decode((string)$response->getBody(), true);
    }

    public function token()
    {
        $response = (new Client)->get('https://api.weixin.qq.com/cgi-bin/token', [
            'query' => [
                'appid' => config('pay.wechat.miniapp_id'),
                'secret' => config('pay.wechat.miniapp_key'),
                'grant_type' => 'client_credential',
            ]
        ]);

        return json_decode((string)$response->getBody(), true);
    }
}
4年前 评论
lanffff (楼主) 4年前
Tinywan 4年前
快乐壮

不是有一个叫easywechat的东西吗?

4年前 评论
bing8u

@1135782926 easywechat 是挺全面的,但用不到公众号开发那些的,仅几个方法就可以完成的,何必要引入呢

4年前 评论
Tinywan

GuzzleHttp\Client

4年前 评论

我在引入微信提供的 解码文件的时候 报错 致命错误: Class 'wxBizDataCrypt' not found 我是按照教程 放在 thinkPHP文件extend 下面

file 引用 file 使用 file 报错

file

这问题 很是头疼 不知哪位大神 帮帮忙

3年前 评论

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