php使用webman框架创建h5跳转小程序的签名

4 阅读1分钟

1、创建公共类 `<?php namespace app\controller;

use support\Request; use support\Cache;

class WechatController { // 公众号 A 的配置 private appId=公众号Aappid;privateappId = '公众号A的appid'; private appSecret = '公众号A的appsecret';

/**
 * 获取 access_token(带缓存)
 */
protected function getAccessToken()
{
    $cacheKey = 'wechat_access_token_a';
    $token = Cache::get($cacheKey);
    if (!$token) {
        $url = "https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid={$this->appId}&secret={$this->appSecret}";
        $res = json_decode(file_get_contents($url), true);
        if (isset($res['access_token'])) {
            $token = $res['access_token'];
            Cache::set($cacheKey, $token, 7000);
        } else {
            // 记录错误日志
            return null;
        }
    }
    return $token;
}

/**
 * 获取 jsapi_ticket(带缓存)
 */
protected function getJsApiTicket()
{
    $cacheKey = 'wechat_jsapi_ticket_a';
    $ticket = Cache::get($cacheKey);
    if (!$ticket) {
        $token = $this->getAccessToken();
        if (!$token) {
            return null;
        }
        $url = "https://api.weixin.qq.com/cgi-bin/ticket/getticket?access_token={$token}&type=jsapi";
        $res = json_decode(file_get_contents($url), true);
        if (isset($res['ticket'])) {
            $ticket = $res['ticket'];
            Cache::set($cacheKey, $ticket, 7000);
        } else {
            return null;
        }
    }
    return $ticket;
}

/**
 * 生成签名
 * @param string $url 当前页面完整 URL(不含#)
 * @return array|null
 */
protected function generateSignature($url)
{
    $ticket = $this->getJsApiTicket();
    if (!$ticket) {
        return null;
    }

    $timestamp = time();
    $nonceStr = $this->createNonceStr();

    $string = "jsapi_ticket={$ticket}&noncestr={$nonceStr}&timestamp={$timestamp}&url={$url}";
    $signature = sha1($string);

    return [
        'appId'     => $this->appId,      // 公众号A的appId
        'timestamp' => $timestamp,
        'nonceStr'  => $nonceStr,
        'signature' => $signature,
    ];
}

protected function createNonceStr($length = 16)
{
    $chars = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789';
    $str = '';
    for ($i = 0; $i < $length; $i++) {
        $str .= substr($chars, mt_rand(0, strlen($chars) - 1), 1);
    }
    return $str;
}

/**
 * 渲染打开小程序的页面(后端输出HTML)
 */
public function openMiniApp(Request $request)
{
    // 获取当前页面的完整 URL(用于签名)
    $protocol = $request->header('x-forwarded-proto', 'http');
    $fullUrl = $protocol . '://' . $request->host() . $request->uri();
    $url = explode('#', $fullUrl)[0]; // 去除 # 部分

    $signPackage = $this->generateSignature($url);
    if (!$signPackage) {
        return '签名生成失败';
    }

    // 返回视图,传递签名数据 以及 客户B的小程序信息
    return view('wechat/open_miniapp', [
        'signPackage' => $signPackage,
        'targetAppId' => 'gh_xxxxxx', // 客户B的小程序原始ID(gh_开头)
        'targetPath'  => '/pages/index/index', // 目标小程序路径
    ]);
}
//备用生成签名的方法
public function getJssdkConfig(Request $request)

{ url=url = request->get('url'); // 前端传递的当前页面 URL if (!$url) { return json(['code' => 400, 'msg' => 'missing url']); }

// 可选:对 URL 进行简单校验,确保是合法格式
if (!filter_var($url, FILTER_VALIDATE_URL)) {
    return json(['code' => 400, 'msg' => 'invalid url']);
}

$ticket = $this->getJsApiTicket(); // 获取 jsapi_ticket
if (!$ticket) {
    return json(['code' => 500, 'msg' => 'get ticket failed']);
}

$timestamp = time();
$nonceStr = $this->createNonceStr();

// 注意:参数顺序必须按字典序排序
$string = "jsapi_ticket={$ticket}&noncestr={$nonceStr}&timestamp={$timestamp}&url={$url}";
$signature = sha1($string);

return json([
    'code' => 0,
    'data' => [
        'appId'     => $this->appId,
        'timestamp' => $timestamp,
        'nonceStr'  => $nonceStr,
        'signature' => $signature,
    ]
]);

} }` 2、这边用于签名的appid和app_secret是公众号的,并且这个公众号是已认证的服务号 3、公众号需要配置域名,在公众号开发设置里,配置jssdk域名