[深入系列]MCJE微軟正版登錄流程#服務(wù)器篇
# 前言&背景
我之前寫了?CV21783605 這篇講述客戶端如何獲得 access token, 那么服務(wù)器是如何驗(yàn)證玩家的呢? 本篇將會(huì)為您解答
# 大體流程
其實(shí)mc驗(yàn)證有多種方式 (它那個(gè)驗(yàn)證的方法有兩個(gè)實(shí)現(xiàn), 一個(gè)是com.mojang.authlib.yggdrasil.YggdrasilMinecraftSessionService那里, 一個(gè)是com.mojang.authlib.legacy.LegacyMinecraftSessionService那里) 我猜前者是外置登錄, 后者是正版, 只是猜而已。這里只講正版
然后mojang提供了一個(gè)api, 讓客戶端驗(yàn)證自己的身份, 并問客戶端要連接那個(gè)服務(wù)器。而服務(wù)器也會(huì)請(qǐng)求它, 如果就是客戶端要連接的,那么api就會(huì)放行。于是驗(yàn)證結(jié)束。
以下是客戶端嘗試加入服務(wù)器的幾個(gè)階段
HELLO,
KEY,
AUTHENTICATING,
NEGOTIATING,
READY_TO_ACCEPT,
DELAY_ACCEPT,
ACCEPTED;
# 具體實(shí)現(xiàn)
由于本人對(duì)加密方面知識(shí)和別的數(shù)學(xué)知識(shí)了解甚少, 有些內(nèi)容我不得不略過(或是只提供猜測), 有大佬可以在評(píng)論區(qū)補(bǔ)充。
首先是Hello階段:
(注: 我刪掉了一些不太重要的代碼)
首先客戶端會(huì)給服務(wù)端發(fā)自己的profile, 大概就是個(gè)玩家的uuid + name, 服務(wù)器會(huì)判斷是否要登陸(是不是離線模式),然后決定直接放行還是走驗(yàn)證流程。這里會(huì)給一個(gè)public key, 這里我猜是個(gè)非對(duì)稱加密, 還會(huì)帶一個(gè)nonce, 也是個(gè)驗(yàn)證手段
這里前半段是自己生成了個(gè)private key,然后直接當(dāng)標(biāo)識(shí)符和server生成的public key以及那個(gè)nonce給hash了一下(就是那個(gè)generateServerId, 這個(gè)的實(shí)現(xiàn)就是個(gè)sha-1),最后發(fā)給了一個(gè)mojang的api https://session.minecraft.net/game/joinserver.jsp 然后會(huì)開個(gè)加密(這里我沒看懂其實(shí)現(xiàn), 應(yīng)該是用了之前發(fā)的那個(gè)public key把自己生成的private key加密了, 但我不確定)
發(fā)的這個(gè)操作是由joinServerSession實(shí)現(xiàn)的
此處的JOIN_URL是?https://session.minecraft.net/game/joinserver.jsp 。其中那個(gè)concatenateURL就是把那個(gè)map里面的東西變成?.../joinserver.jsp?user=...&sessionId=...&serverId=...
然后api會(huì)返回一個(gè)表示, ok就是成功
這時(shí)就到了KEY階段
服務(wù)器會(huì)把客戶端發(fā)的那個(gè)private key解密(真就把key當(dāng)標(biāo)識(shí)符了), 然后就開始Authenticating階段
然后給各位看一下那個(gè)hasJoinedServer方法
和之前那個(gè)joinServer一樣, 但是CHECK_URL是?session.minecraft.net/game/checkserver.jsp?user=...&serverId=...
serverId應(yīng)該和客戶端那個(gè)一樣。如果一樣,他就會(huì)yes, 驗(yàn)證通過,服務(wù)器就會(huì)把狀態(tài)變成ready to accept。然后就是在tick的時(shí)候進(jìn)行一些黑名單, 服務(wù)器滿員什么的檢查, 然后就accepted。
沒了
# 樣例
我:?session.minecraft.net/game/joinserver.jsp?user=張三&sessionId=用上一個(gè)專欄的python文件產(chǎn)生的密鑰&serverId=114514
api: 過
我:?session.minecraft.net/game/checkserver.jsp?user=張三&serverId=114514
api: 過
我: 高高興興玩服務(wù)器咯
(ps 那個(gè)id好像沒有限制 所以可以亂寫 只要兩邊一樣就成