微信小游戲登錄流程【轉】


花了好幾天時間,總算解決了微信小游戲的登錄。本來微信登錄就比較復雜,再加上前前后后改了些接口,更是痛苦。網上找到的資料總是些零零散散有新有舊,微信自己的文檔大致有一個流程,但一些要點和注意事項又語焉不詳。今天就從頭到尾整理一遍登錄過程吧,算是造福一下本就很苦鱉的程序猿,順便給自己也留個記錄。
 
    首先介紹下這個流程的背景,這樣的話各位讀者就可以判斷,這對自己是不是有用了。當然,我相信在大多數情況下都是有用的。
 

一、這個流程是按照強聯網游戲來設計的,客戶端跟服務器通信用的是WebSocket,服務器端是Node.js。(如果你的服務器是PHP,那么流程可能更簡化一些)
 
二、玩家以純粹的新人身份進入游戲。(也就是,不假設玩家提前關注了相關公眾號之類的)
 
三、最終目的是獲取unionId。(如果你只想要openId,甚至連openId都不要,只要昵稱頭像,那可以更簡單。關於unionId和openId的區別,這里就不啰嗦了,相信大家都很清楚。)
 

登錄過程中比較麻煩的是用戶信息授權按鈕的處理,我沒有找到合適的辦法把它融合到流程中間,所以干脆就放最前面。在操作體驗上,就是玩家第一次進入游戲時,需要先點一個【微信登錄】的按鈕,授權游戲獲取用戶信息,然后再開始游戲。當然,以后再進游戲的話,因為已經授權過,所以就不會再有這個按鈕了。
 

那么下面就開始介紹流程了。
 

1、在客戶端,調用wx.getSetting檢查是否獲得授權。如果已經授權,進入下一步;否則,調用wx.createUserInfoButton顯示授權按鈕。
 
    這一步通常會在游戲的登錄界面上,這個時候不會有【開始游戲】、【選擇服務器】之類的,而是一個【微信登錄】按鈕。點擊【微信登錄】,微信會提示用戶是否允許游戲訪問他的信息。允許之后,【微信登錄】消失,界面上會出現【開始游戲】或者【選擇服務器】的畫面。
 
    如果用戶拒絕的話,最好也給一個彈窗,解釋為什么需要授權。

wx.getSetting({
	success(res)
	{
		// 已授權
		if (res.authSetting["scope.userInfo"])
		{
			// 進入下一步,比如【選擇服務器】
		}
		// 顯示授權按鈕
		else
		{
			let sysInfo = wx.getSystemInfoSync();
			let button = wx.createUserInfoButton({
				type: "text",
				text: "微信登錄",
				style: {
					left: sysInfo.windowWidth / 2 - 50,
					top: sysInfo.windowHeight / 2 - 30,
					width: 100,
					height: 60,
					backgroundColor: "#c7a976",
					color: "#5c5941",
					borderColor: "#5c5941",
					textAlign: "center",
					fontSize: 16,
					borderWidth: 4,
					borderRadius: 4,
					lineHeight: 60,
				}
			});
			button.onTap(function(res)
			{
				if (res.userInfo)
				{
					button.destroy();
					// 進入下一步,比如【選擇服務器】
				}
				else
				{
					wx.showModal({
						title: "溫馨提示",
						content: "《XXX》是一款在線對戰游戲,需要您的用戶信息登錄游戲。",
						showCancel: false,
					});
				}
			});
			button.show();
		}
	}
});

2、對於需要分區跨服的游戲,顯示【選擇服務器】的界面。
 
    ​如果不需要分區,那么可以顯示一個【開始游戲】的界面(你也許覺得這一步可以省掉,但是為了結構清晰,我建議還是留着)。
 
    ​這一步是游戲自己處理,跟微信無關,所以就沒代碼了。
  
3、連接游戲服務器;
 
    在連接成功的回調里,調用wx.login,獲得code;
 
    再調用wx.getUserInfo,獲得encryptedData和iv;
 
    最后將code、encryptedData、iv發送給服務器。
 
    因為用的是WebSocket,需要連接服務器的步驟,就在這里了。如果是PHP,可以省掉連接服務器,直接開始調用wx.login。
 
    這一步獲得的參數很重要:code將被用來獲取sessionKey;而sessionKey、encryptedData、iv三者一起解出用戶的敏感數據(包括unionId等)。
 

// 連接游戲服務器成功的回調。如果服務器用的是PHP,這里直接調用wx.login
onConnected: function()
{
    wx.login({
        success: function(res)
        {
            // res中包含code
            
            // 獲取用戶信息
            wx.getUserInfo({
                withCredentials: true,      // 必須在wx.login之后,這里才能為true
                success: function(result)
                {
                    // result中包含encryptedData和iv
                    
                    // 將res.code、result.encryptedData、result.iv發送到服務器
                },
                fail: function(result)
                {
                    // 錯誤處理
                },
            });
        },
        fail: function(res)
        {
            // 錯誤處理
        },
    });
 
},

4、在服務器上收到數據后,首先調用微信的接口 https://api.weixin.qq.com/sns/jscode2session
 
    這一步需要code,以及你的小游戲AppID和AppSecret,這兩個可以在微信公眾平台管理后台拿到。
 
    值得一提的是,在微信后台上,AppSecret只能查看一次,然后你需要自己把它保存在某個隱秘的地方。如果你忘了保存,那么只能再重新生成一個AppSecret。
 

調用成功之后,可以拿到sessionKey。(同時還有openId)
 
   然后,用sessionKey以及之前客戶端傳來的encryptedData、iv,解密得到unionId、openId、昵稱、頭像等等。有了這些數據,就可以開始游戲里的登錄了。
 
    需要注意的是,小游戲要綁定了公眾號才有unionId。

// 服務器端的代碼
let https = require("https");
let iconv = require("iconv-lite");
// WXBizDataCrypt是微信提供的模塊,用來執行解密
// 可以在https://developers.weixin.qq.com/minigame/dev/tutorial/open-ability/signature.html找到下載鏈接
let WXBizDataCrypt = require("../lib/WXBizDataCrypt.js");
 
// WX_APP_ID是小游戲AppID,WX_APP_SECRET是小游戲AppSecret,code由客戶端發送上來
let url = "https://api.weixin.qq.com/sns/jscode2session?appid=" + WX_APP_ID + "&secret=" + WX_APP_SECRET + "&js_code=" + code + "&grant_type=authorization_code";
let req = https.get(url, function(res)
{
    let datas = [];
    let size = 0;
    res.on("data", function(data)
    {
        datas.push(data);
        size += data.length;
    });  
    res.on("end", function()
    {
        let buff = Buffer.concat(datas, size);
        let result = iconv.decode(buff, "utf8");
        
        try
        {
            let d = JSON.parse(result);
            if (d.session_key)
            {
                try
                {
                    let wxCrypt = new WXBizDataCrypt(WX_APP_ID, d.session_key);
 
                    // encryptedData和iv都是客戶端傳遞的數據
                    let res = wxCrypt.decryptData(encryptedData, iv);
 
                    // res中包含了openId、unionId、nickName、avatarUrl等等信息
                    // 注意,如果你的小游戲沒有綁定微信公眾號,這里可能也不會有unionId
                    // 微信登錄完成,可以開始進入游戲了
                }
                catch (error)
                {
                    // 錯誤處理
                }
            }
            else
            {
                // 錯誤處理
            }
        }
        catch (error)
        {
            // 錯誤處理
        }
    });
});
req.on("error", function(err)
{
    // 錯誤處理
});

整個微信小游戲登錄過程,大致就是這樣了。最后順便提一下,調用https://api.weixin.qq.com/sns/jscode2session這一步,因為是https請求,所以你可能會覺得,也可以直接在客戶端調用。畢竟code就在客戶端,AppID和AppSecret也是固定的。但微信並不建議這么做(想想看,微信甚至不會替你保存AppSecret,你願意把它放客戶端里嗎?)
————————————————

原文鏈接:https://blog.csdn.net/SingleWizard/article/details/85252875


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM