Unity&WeChat公式アカウント-コードをスキャンしてフォローし、ログインします

機能要件:ログイン時に公式アカウントのQRコードが表示されます。ユーザーがQRコードをスキャンした後、[フォロー]をクリックすると、イベントがプログラムに応答し、ログインが実現します。 

実装手順:

1.公式アカウントは、開発者アカウントになるために申請し、AppIDとAppSecretを取得します。

2.IPアドレスのホワイトリストとサーバー構成を設定します。

3.クレデンシャルaccess_tokenを呼び出すグローバルに一意のインターフェイスを取得します。

4.生成されたQRコードインターフェイスを呼び出してチケットを取得します。

5.チケットをQRコードに交換します。

6.ユーザーインタラクションイベントプッシュ。

具体操作:

1.公式アカウントで開発者アカウントを申請し、AppIDとAppSecretを取得します。

WeChat公式アカウントプラットフォームにログインし、[設定と開発]列で基本構成を確認すると、開発者ID(AppID)が表示され、開発者パスワード(App Secret)が有効になります。AppSecretに注意してください。成功したイネーブルメントインターフェイスに保存および記録されます。閉じた後は、二度と表示されません。

2.IPアドレスのホワイトリストとサーバー構成を設定します。

AppSecret開発者パスワードを有効にすると、IPホワイトリストの構成内容が表示され、access_tokenを定期的に取得するために使用するサーバーIPアドレスが追加されます。

IPアドレスがわからない場合は、ブラウザからこのURLにアクセスして、次のクエリを実行できます。

https://ip.skk.moe/

サーバー構成で、[構成の変更]をクリックし、独自のサーバーアドレスとその他の関連コンテンツを入力します。

3.クレデンシャルaccess_tokenを呼び出すグローバルに一意のインターフェイスを取得します。

以下は、WeChatOpenDocumentでaccess_tokenを取得するための手順です。

access_token是公众号的全局唯一接口调用凭据,公众号调用各接口时都需使用access_token。
开发者需要进行妥善保存。access_token的存储至少要保留512个字符空间。
access_token的有效期目前为2个小时,需定时刷新,重复获取将导致上次获取的access_token失效。

公众平台的API调用所需的access_token的使用及生成方式说明:
1、建议公众号开发者使用中控服务器统一获取和刷新access_token,其他业务逻辑服务器所使用的access_token
均来自于该中控服务器,不应该各自去刷新,否则容易造成冲突,导致access_token覆盖而影响业务;
2、目前access_token的有效期通过返回的expire_in来传达,目前是7200秒之内的值。
中控服务器需要根据这个有效时间提前去刷新新access_token。在刷新过程中,
中控服务器可对外继续输出的老access_token,此时公众平台后台会保证在5分钟内,
新老access_token都可用,这保证了第三方业务的平滑过渡;
3、access_token的有效时间可能会在未来有调整,所以中控服务器不仅需要内部定时主动刷新,
还需要提供被动刷新access_token的接口,这样便于业务服务器在API调用获知access_token已
超时的情况下,可以触发access_token的刷新流程。
4、对于可能存在风险的调用,在开发者进行获取 access_token调用时进入风险调用确认流程,
需要用户管理员确认后才可以成功获取。具体流程为:
开发者通过某IP发起调用->平台返回错误码[89503]并同时下发模板消息给公众号管理员->公众号管理员
确认该IP可以调用->开发者使用该IP再次发起调用->调用成功。
如公众号管理员第一次拒绝该IP调用,用户在1个小时内将无法使用该IP再次发起调用,
如公众号管理员多次拒绝该IP调用,该IP将可能长期无法发起调用。
平台建议开发者在发起调用前主动与管理员沟通确认调用需求,或请求管理员开启IP白名单功能并将
该IP加入IP白名单列表。

インターフェイス呼び出し要求の説明:

httpsリクエストメソッド:GET

https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=APPID&secret=APPSECRET

応答パラメーターの説明:

Unityでこのデータ構造を定義します。

/// <summary>
/// 获取access_token接口的响应结构
/// </summary>
[Serializable]
public class GetTokenResponse
{
    /// <summary>
    /// 获取到的凭证
    /// </summary>
    public string access_token;
    /// <summary>
    /// 凭证有效时间,单位:秒
    /// </summary>
    public int expires_in;
}

 インターフェイスを呼び出すGETメソッド:

using System;
using UnityEngine;
using System.Collections;
using UnityEngine.Networking;

public class GetTokenExample : MonoBehaviour
{
    //开发者ID
    private const string appId = "";
    //开发者密码
    private const string appSecret = "";

    private void Start()
    {
        StartCoroutine(RequestCoroutine());
    }
    private IEnumerator RequestCoroutine()
    {
        string url = $"https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid={appId}&secret={appSecret}";

        using(UnityWebRequest request = UnityWebRequest.Get(url))
        {
            yield return request.SendWebRequest();
            if (request.result == UnityWebRequest.Result.Success)
            {
                //这里使用LitJson反序列化 也可以使用其他序列化/反序列化工具
                var response = JsonMapper.ToObject<GetTokenResponse>(request.downloadHandler.text);
                Debug.Log($"获取到的access_token:{response.access_token}");
                Debug.Log($"access_token有效时间:{response.expires_in}秒");
            }
            else
            {
                Debug.LogError($"获取access_token失败:{request.error}");
            }
        }
    }
}

4. QRコード生成インターフェイスを呼び出して、チケットを取得します。

現在、QRコードには一時的なQRコードと永続的なQRコードの2種類があります。一時的なQRコードを取得する例を次に示します。

インターフェイス呼び出し要求の説明:

httpリクエストメソッド:POST

https://api.weixin.qq.com/cgi-bin/qrcode/create?access_token=TOKEN

POSTデータ形式:json

データサンプル:

{
	"expire_seconds": 604800,
	"action_name": "QR_SCENE",
	"action_info": {
		"scene": {
			"scene_id": 123
		}
	}
}

パラメータの説明:

応答パラメーターの説明:

Unityで上記のデータ構造を定義します:(上記のデータサンプル構造に注意してください)

[Serializable]
public class GetTicketPost
{
    /// <summary>
    /// 该二维码有效时间,以秒为单位。 最大不超过2592000(即30天),此字段如果不填,则默认有效期为60秒。
    /// </summary>
    public int expire_seconds;
    /// <summary>
    /// 二维码类型,QR_SCENE为临时的整型参数值,QR_STR_SCENE为临时的字符串参数值,QR_LIMIT_SCENE为永久的整型参数值,QR_LIMIT_STR_SCENE为永久的字符串参数值
    /// </summary>
    public string action_name;
    /// <summary>
    /// 二维码详细信息
    /// </summary>
    public ActionInfo action_info;
}
[Serializable]
public class ActionInfo
{
    public SceneInfo scene;
}
[Serializable]
public class SceneInfo
{
    /// <summary>
    /// 场景值ID,临时二维码时为32位非0整型,永久二维码时最大值为100000(目前参数只支持1--100000)
    /// </summary>
    public int scene_id;
    /// <summary>
    /// 场景值ID(字符串形式的ID),字符串类型,长度限制为1到64
    /// </summary>
    public string scene_str;
}
[Serializable]
public class GetTicketResponse
{
    /// <summary>
    /// 获取的二维码ticket,凭借此ticket可以在有效时间内换取二维码。
    /// </summary>
    public string ticket;
    /// <summary>
    /// 该二维码有效时间,以秒为单位。 最大不超过2592000(即30天)。
    /// </summary>
    public int expire_seconds;
    /// <summary>
    /// 二维码图片解析后的地址,开发者可根据该地址自行生成需要的二维码图片
    /// </summary>
    public string url;
}

インターフェイスを呼び出すPOSTメソッド:

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

public class GetTicketExample : MonoBehaviour
{
    private const string access_token = "";
    
    private void Start()
    {
        StartCoroutine(RequestCoroutine());
    }
    private IEnumerator RequestCoroutine()
    {
        string url = $"https://api.weixin.qq.com/cgi-bin/qrcode/create?access_token={access_token}";
        var data = new GetTicketPost()
        {
            expire_seconds = 604800,
            action_name = "QR_STR_SCENE",
            action_info = new ActionInfo()
            {
                scene = new SceneInfo()
                {
                    scene_id = 123,
                    scene_str = "test"
                }
            }
        };
        using (UnityWebRequest request = UnityWebRequest.Post(url, UnityWebRequest.kHttpVerbPOST))
        {
            string json = JsonMapper.ToJson(data);
            byte[] bytes = Encoding.UTF8.GetBytes(json);
            request.uploadHandler = new UploadHandlerRaw(bytes);
            request.downloadHandler = new DownloadHandlerBuffer();
            yield return request.SendWebRequest();
            if (request.result == UnityWebRequest.Result.Success)
            {
                Debug.Log(request.downloadHandler.text);
                //这里使用LitJson反序列化 也可以使用其他序列化/反序列化工具
                var response = JsonMapper.ToObject<GetTicketResponse>(request.downloadHandler.text);
                Debug.Log($"获取到的ticket:{response.ticket}");
                Debug.Log($"有效时间:{response.expire_seconds}秒");
                Debug.Log($"url:{response.url}");
            }
            else
            {
                Debug.LogError($"获取ticket失败:{request.error}");
            }
        }
    }
}

公式アカウントに上記のインターフェースの権限があることを確認するには、[設定と開発/インターフェースの権限]で確認してください。

5.QRコードをチケットと交換します。

チケットを取得したら、QRコード画像と交換するために使用できます。インターフェースリクエストの説明:

httpsリクエストメソッド:GET

https://mp.weixin.qq.com/cgi-bin/showqrcode?ticket=TICKET

TICKETコンテンツにはUrlEncodeエンコーディングが必要です。コードは次のとおりです。

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

/// <summary>
/// ticket换取二维码
/// </summary>
public class GetQRCodeExample : MonoBehaviour
{
    private const string ticket = "gQHc7zwAAAAAAAAAAS5odHRwOi8vd2VpeGluLnFxLmNvbS9xLzAyQWIwbzlOYVg4eVAxN3YtV055Y0UAAgRfRDFiAwSAOgkA";

    private void Start()
    {
        StartCoroutine(RequestCoroutine());
    }
    private IEnumerator RequestCoroutine()
    {
        string url = $"https://mp.weixin.qq.com/cgi-bin/showqrcode?ticket={UrlEncode(ticket)}";

        using (UnityWebRequest request = UnityWebRequest.Get(url))
        {
            request.downloadHandler = new DownloadHandlerTexture();
            yield return request.SendWebRequest();
            if (request.result == UnityWebRequest.Result.Success)
            {
                Texture2D qrcode = DownloadHandlerTexture.GetContent(request);
                Sprite sprite = Sprite.Create(qrcode, new Rect(0, 0, 430, 430), Vector2.zero);
                new GameObject("二维码").AddComponent<SpriteRenderer>().sprite = sprite;
            }
            else
            {
                Debug.LogError($"ticket换取二维码失败:{request.error}");
            }
        }
    }
    public string UrlEncode(string content)
    {
        StringBuilder sb = new StringBuilder();
        foreach (char ch in content)
        {
            if (ch >= '0' && ch <= '9')
            {
                sb.Append(ch);
            }
            else if (ch >= 'a' && ch <= 'z' || ch >= 'A' && ch <= 'Z')
            {
                sb.Append(ch);
            }
            else if (ch >= 0x4e00 && ch <= 0x9fa5)
            {
                foreach (byte b in Encoding.UTF8.GetBytes(ch.ToString()))
                {
                    sb.Append(@"%" + b.ToString("X"));
                }
            }
            else if ('-' == ch || '_' == ch || '.' == ch || '+' == ch || '*' == ch || '(' == ch || ')' == ch
                      || ',' == ch || '&' == ch || '/' == ch || ':' == ch || ';' == ch || '=' == ch || '?' == ch
                      || '@' == ch || '`' == ch || '^' == ch || '[' == ch || ']' == ch || '<' == ch || '>' == ch)
            {
                sb.Append(ch);
            }
            else
            {
                foreach (byte b in Encoding.UTF8.GetBytes(ch.ToString()))// -_.+*(),&/:;=?@`~^[]<>
                {
                    sb.Append(@"%" + b.ToString("X"));
                }
            }
        }
        return sb.ToString();
    }
}

図に示すように、SpriteRendererを介してQRコードを表示しました:(規制に違反しないように、QRコードはモザイクになっています)

6.ユーザーインタラクションイベントプッシュ:

WeChatユーザーと公式アカウントとのやり取り中に、ユーザーの特定の操作により、WeChatサーバーはイベントプッシュを通じて開発者センターで開発者が設定したサーバーアドレスに通知し、開発者が情報を取得できるようにします。

コンテンツ

(1)イベントのフォロー/フォロー解除

(2)パラメータを使用したQRコードイベントのスキャン

(3)ジオロケーションイベントの報告

(4)カスタムメニューイベント

(5)メニューをクリックしてメッセージをプルするときのイベントプッシュ

(6)メニュージャンプリンクをクリックしたときのイベントプッシュ

項目(2)を使用し、オープンドキュメントの関連する手順は次のとおりです。

ユーザーがシーン値を使用してQRコードをスキャンすると、次の2つのイベントがプッシュされる可能性があります。

        1)ユーザーが公式アカウントをフォローしていない場合、ユーザーは公式アカウントをフォローできます。アカウントをフォローした後、WeChatはシーン値を持つ次のイベントを開発者にプッシュします。

        2)ユーザーが公式アカウントをフォローしている場合、WeChatはシーン値を含むスキャンイベントを開発者にプッシュします。

ユーザーがフォローしない場合、フォロー後のイベントプッシュは次のようになります:(データ形式はXMLです)

<xml>
  <ToUserName><![CDATA[toUser]]></ToUserName>
  <FromUserName><![CDATA[FromUser]]></FromUserName>
  <CreateTime>123456789</CreateTime>
  <MsgType><![CDATA[event]]></MsgType>
  <Event><![CDATA[subscribe]]></Event>
  <EventKey><![CDATA[qrscene_123123]]></EventKey>
  <Ticket><![CDATA[TICKET]]></Ticket>
</xml>

パラメータの説明:

ユーザーがフォローしたときのイベントプッシュは次のとおりです。

<xml>
  <ToUserName><![CDATA[toUser]]></ToUserName>
  <FromUserName><![CDATA[FromUser]]></FromUserName>
  <CreateTime>123456789</CreateTime>
  <MsgType><![CDATA[event]]></MsgType>
  <Event><![CDATA[SCAN]]></Event>
  <EventKey><![CDATA[SCENE_VALUE]]></EventKey>
  <Ticket><![CDATA[TICKET]]></Ticket>
</xml> 

パラメータの説明:

手順5で、QRコード画像を取得しました。このとき、ユーザーはQRコードをスキャンしてフォローするか、すでにフォローしています。WeChatサーバーは、上記の2つのイベントデータを自分で設定したサーバーアドレスにプッシュします。 Unityクライアント。独自のサーバーにデータ要求を送信し、ユーザーインタラクションイベントのデータ(フォローまたはフォロー済み)に従ってユーザーがログインできるかどうかを判断する必要があります。

  パブリックアカウント「ContemporaryWildProgrammer」へようこそ

おすすめ

転載: blog.csdn.net/qq_42139931/article/details/123500045