Unity PC端使用微信扫码,PHP登录网站应用

一、获取Code

以下过程耗费数日之久,我们不断遭遇redirect_uri、scope 错误,以及需要在微信端打开的提示。经过详尽的网站和客服信息查阅,进行了无数次的测试后,终于成功解决了问题。现在我们将这些经验记录下来,希望能帮助其他人少走弯路。

总结,首先在微信开放平台创建网站应用,其次

1、在网站应用授权回调域,填写顶级域名,且不带https://,例如填写baidu.com或www.baidu.com

2、编写测试文件cs.PHP,并上传到服务器,注意redirect_uri的处理,增加https://和urlencodec处理

<?php

// 应用的AppID和redirect_uri,需要替换为你自己的
$appid = '你的appid';
$redirect_uri = urlencode('https://baidu.com/a/callback.php'); // 平台配置授权回调域为baidu.com
$scope = 'snsapi_login'; // 授权作用域,一般为snsapi_login,详情参考微信开放平台文档

// 构造授权链接
$login_url = 'https://open.weixin.qq.com/connect/qrconnect?';
$login_url .= 'appid=' . $appid;
$login_url .= '&redirect_uri=' . $redirect_uri;
$login_url .= '&response_type=code';
$login_url .= '&scope=' . $scope;
$login_url .= '#wechat_redirect';

// 输出登录链接
echo '<a href="'.$login_url.'">使用微信扫码登录</a>';

?>

 3、编写callback.php,该文件假设已上传到网站目录/a/callback.php

<?php

// 微信扫码登录授权后的回调处理页面

$appId = '你的appId';
$appSecret = '你的appSecret';//都在网页应用上
$code = $_GET['code'];

// Step 1: 获取 Access Token
$url = "https://api.weixin.qq.com/sns/oauth2/access_token?appid=$appId&secret=$appSecret&code=$code&grant_type=authorization_code";
$response = file_get_contents($url);
$params = json_decode($response, true);

$accessToken = $params['access_token'];
$openId = $params['openid'];

// Step 2: 获取用户信息
$url = "https://api.weixin.qq.com/sns/userinfo?access_token=$accessToken&openid=$openId";
$userInfo = file_get_contents($url);
$userInfo = json_decode($userInfo, true);

// 打印用户信息
echo "<pre>";
print_r($userInfo);
echo "</pre>";

// 可以根据需要处理用户信息,比如保存到数据库,完成登录等操作
?>

4、测试成功后,则可以在PC端打开以下链接:

https://open.weixin.qq.com/connect/qrconnect?appid=APPID&redirect_uri=REDIRECT_URI&response_type=code&scope=snsapi_login&state=STATE#wechat_redirect

该链接需要修改APPID为你的、REDIRECT_URI为你的、STATE为随机数

二、Unity登录微信

根据官方文旦,构造授权链接
https://open.weixin.qq.com/connect/qrconnect?appid=wxbdc5610cc59c1631&redirect_uri=https%3A%2F%2Fpassport.yhd.com%2Fwechat%2Fcallback.do&response_type=code&scope=snsapi_login&state=3d6be0a4035d839573b04816624a415e#wechat_redirect
其中各个参数根据你申请的应用参数而定。
执行https请求,可以抓取到网页源码,解析出wrp_code节点的src的值,比如这里是:
/connect/qrcode/021XYI6c566IXqbR

然后,就可以构造出二维码的url了,就是前面拼接上域名https://open.weixin.qq.com/,即
https://open.weixin.qq.com/connect/qrcode/021XYI6c566IXqbR
然后在Unity中,我们就可用通过UnityWebRequest类加载出二维码的Texture了,直接在UI上显示出来。

using System;
using System.Collections;
using UnityEngine;
using UnityEngine.Networking;
using System.Text.RegularExpressions;
using UnityEngine.UI;

public class Main : MonoBehaviour
{
    public RawImage qrcodeImg;

    void Start()
    {
        StartCoroutine(SendRequest());
    }

    /// <summary>
    /// 开启一个协程,发送请求
    /// </summary>
    /// <returns></returns>
    IEnumerator SendRequest()
    {
        string url = @"https://open.weixin.qq.com/connect/qrconnect?appid=wxbdc5610cc59c1631&redirect_uri=https%3A%2F%2Fpassport.yhd.com%2Fwechat%2Fcallback.do&response_type=code&scope=snsapi_login&state=3d6be0a4035d839573b04816624a415e#wechat_redirect";
        UnityWebRequest uwr = UnityWebRequest.Get(url);
        yield return uwr.SendWebRequest();                               
        if (uwr.isHttpError || uwr.isNetworkError)                       
        {
            Debug.Log(uwr.error); 
        }
        else 
        {
            string htmlStr = uwr.downloadHandler.text;
            //Debug.Log(htmlStr);
            //使用正则表达式匹配搜索qrcode图片
            string pattern = "qrcode_img\" src=\"(\\S*)\"";
            Regex rgx = new Regex(pattern);
            Match m = rgx.Match(htmlStr);
            if(null != m)
            {
                //二维码的链接
                string qrcodeUrl = "https://open.weixin.qq.com" + m.Groups[1].Value;
                //获取二维码图片
                UnityWebRequest qrcodeUwr = UnityWebRequest.Get(qrcodeUrl);
                yield return qrcodeUwr.SendWebRequest();
                if (qrcodeUwr.isHttpError || qrcodeUwr.isNetworkError)
                {
                    Debug.Log(qrcodeUwr.error);
                }
                else
                {
                    //二维码的二进制流
                    var qrcodeBytes = qrcodeUwr.downloadHandler.data;
                    //转换成Texture,给RawImage显示
                    Texture2D tex2D = new Texture2D(256, 256);
                    tex2D.LoadImage(qrcodeBytes);
                    qrcodeImg.texture = tex2D;
                }
            }
        }
    }
}

三、Unity获取微信已登录消息

访问登录页的链接是 https://open.weixin.qq.com/connect/qrconnect。在用户允许授权后,会重定向到指定的 redirect_uri,并附带 code 和 state 参数。如果用户禁止授权,则重定向后只会带上 state 参数,不包含 code 参数。

第一次发起http请求的时,你进入了微信的扫码界面,这时这个http请求已经结束了。微信会偷偷发起一个长连接用于监听用户的扫码状态,监听包括长时间未扫码、扫码了、授权了、拒绝了授权等操作。你需要通过http请求去获取他监听用户操作的code。我们在Unity客户端可以用UnityWebRequest进行长轮询(可以一秒一次,大概30次请求会超时,如果超时可以进行重新获取二维码的get请求),用于监听手机端用户的扫码状态,当用户扫码时或者用户点击授权、拒绝都会返回相应的code,可以根据这些code在客户端进行处理。如果不进行第二次http请求的长轮询,客户端就算是扫了码也是没有反应的。

第二次的http请求和你那个二维码一样,是都带着uuid的一个链接:https://lp.open.weixin.qq.com/connect/l/qrconnect?uuid=Ha19&_=84141

uuid可以通过第一次连接的返回的text中找到。

游戏开发者需要自行部署一个 web 服务器,并提供一个访问链接作为 redirect_uri。当 redirect_uri 被访问时,web 服务器通知游戏服务器。游戏服务器再通过通信协议告知游戏客户端扫码结果。

重要的是,游戏服务器如何知道哪个客户端应该接收这个回调呢?这是通过 state 参数来判断的。游戏客户端首先应向游戏服务器请求生成一个 state。然后,游戏客户端使用这个 state 去访问登录页链接 https://open.weixin.qq.com/connect/qrconnect。这样,在回调到 redirect_uri 时,游戏服务器就能通过 state 参数确定是哪个游戏客户端发起的扫码授权请求。

将state、openid和登录状态写入新的表,客户端轮询这个表,在30秒内结束,若存在state且登录状态为登录则返回许可并删除相关信息。

退出客户端,向退出Api发送state,然后查询表,写入state和退出状态

每次登入先去查询这个表是否有state是退出状态,若是,则更新表openid中pid的信息,删除state,若pid中已包含多个state,则提示,客户端过多,请退出其他客户端,若不足3个,则追加state,然后将state、openid和允许登录状态写入新表。

 

posted @   多见多闻  阅读(215)  评论(0编辑  收藏  举报
(评论功能已被禁用)
相关博文:
阅读排行:
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
· 【自荐】一款简洁、开源的在线白板工具 Drawnix
· 园子的第一款AI主题卫衣上架——"HELLO! HOW CAN I ASSIST YOU TODAY
· Docker 太简单,K8s 太复杂?w7panel 让容器管理更轻松!
点击右上角即可分享
微信分享提示