我正在编写一个与游戏相关的网站,需要我知道用户的 Steam ID,因此似乎最好的方法是使用我在其他网站上看到的“使用 Steam 登录”按钮来处理我的用户身份验证。我以为这会很简单,但我在实现它时遇到了很多麻烦。
我注册了 Steam API 密钥,一个旧的论坛帖子引导我查看位于 https://developer.valvesoftware.com/wiki/Steam_Web_API#GetPlayerSummaries_.28v0001.29 的文档,不幸的是,这些文档并没有真正描述身份验证流程或如何拨打电话。不幸的是,我似乎在网上找不到太多关于如何做到这一点的其他信息,至少没有直接的信息。
也许我误解了流程,但我预计用户会:
因此,我希望文档能够显示此过程所需的一组示例 Postman API 调用。然而,我没有看到这样的事情。所以我认为我对流程的理解可能是不正确的。
在网站上实现“使用 Steam 登录”按钮的正确方法是什么。
编辑/更新
在 Chat GPT 的帮助下,我取得了一些进展。
然后我构建了一个从我的网站到 Steam 的链接,如下所示:
https://steamcommunity.com/openid/login?openid.ns=http%3A%2F%2Fspecs%2Eopenid%2Enet%2Fauth%2F2%2E0&openid.mode=checkid_setup&openid.return_to=https%3A%2F%2FmySite%2Ecom%2FauthCallback%2Ecfm?serverName=shadygrove&openid.realm=https%3A%2F%2FmySite%2Ecom&openid.ns.sreg=http%3A%2F%2Fopenid%2Enet%2Fextensions%2Fsreg%2F1%2E1&openid.claimed_id=http%3A%2F%2Fspecs%2Eopenid%2Enet%2Fauth%2F2%2E0%2Fidentifier%5Fselect&openid.identity=http%3A%2F%2Fspecs%2Eopenid%2Enet%2Fauth%2F2%2E0%2Fidentifier%5Fselect
这允许登录并成功返回到我的回调页面。然后我尝试使用此代码验证数字签名:
<cfset openid_response = "openid.ns=#url.openid.ns#&openid.mode=#url.openid.mode#&openid.op_endpoint=#url.openid.op_endpoint#&openid.claimed_id=#url.openid.claimed_id#&openid.identity=#url.openid.identity#&openid.return_to=#url.openid.return_to#&openid.response_nonce=#url.openid.response_nonce#&openid.assoc_handle=#url.openid.assoc_handle#&openid.signed=#url.openid.signed#&openid.sig=#url.openid.sig#">
<!-- Calculate the expected signature -->
<cfset expected_signature = hmac(
openid_response,
application.steamKey,
"HmacSHA1",
"UTF-8"
)>
<!-- Compare the calculated signature with the received one -->
<cfif expected_signature eq url.openid.sig>
<cfoutput>Authentication is valid.</cfoutput>
<cfelse>
<cfoutput>Authentication is NOT valid.</cfoutput>
</cfif>
这总是显示为无效。我尝试了大约 10 种其他构建“openid_response”的方法,但它总是返回无效。我尝试过的一些事情:
不幸的是,我找到的唯一其他文档(https://partner.steamgames.com/doc/features/auth#website)提供的细节很少,所以我什至不确定我使用的是正确的算法.
我终于在没有文档帮助的情况下让它工作了。
我的登录按钮是使用此代码生成的:
<cfset steamLoginUrl = "https://steamcommunity.com/openid/login?">
<cfset steamLoginUrl = "#steamLoginUrl#openid.ns=#UrlEncodedFormat("http://specs.openid.net/auth/2.0")#">
<cfset steamLoginUrl = "#steamLoginUrl#&openid.mode=checkid_setup">
<cfset steamLoginUrl = "#steamLoginUrl#&openid.return_to=#UrlEncodedFormat("MyDomain/authCallback.cfm")#">
<cfset steamLoginUrl = "#steamLoginUrl#&openid.realm=#UrlEncodedFormat("MyDomain")#">
<cfset steamLoginUrl = "#steamLoginUrl#&openid.ns.sreg=#UrlEncodedFormat("http://openid.net/extensions/sreg/1.1")#">
<cfset steamLoginUrl = "#steamLoginUrl#&openid.claimed_id=#UrlEncodedFormat("http://specs.openid.net/auth/2.0/identifier_select")#">
<cfset steamLoginUrl = "#steamLoginUrl#&openid.identity=#UrlEncodedFormat("http://specs.openid.net/auth/2.0/identifier_select")#">
<a href="#steamLoginUrl#">
<img src="imgs/steamLogin.png">
</a>
登录后,我收到一个签名,我应该能够使用给定的 API 密钥和 hmac() 函数来验证该签名。我尝试了一百种不同的方法来构造我应该运行的字符串,从使用查询字符串到使用新行(尝试“ "、Chr(10)、Chr(13) 等)分隔的值列表到字段列表以及值到字段列表等于值;没有任何作用。而且我在网上找不到任何明确的文档来说明如何操作它。
但是,我发现这个答案提出了不同的验证方法:Steam OpenID Signature Validation
按照那里的说明,我编写了这段在第一次尝试中就有效的小代码,在我用签名方法将头撞到墙上几个小时之后,这很好。
<cfset checkUrl = cgi.request_url>
<cfset checkUrl = Replace(checkUrl, "MyUrl", "https://steamcommunity.com/openid/login")>
<cfset checkUrl = Replace(checkUrl, "&openid.mode=id_res", "&openid.mode=check_authentication")>
<cfhttp url="#checkUrl#" />
<cfif cfhttp.fileContent contains "is_valid:true">
Do stuff...
<cfelse>
Do other stuff...
</cfif>
这似乎有效。然而,我仍然很想知道如何真正让服务器端签名验证在 Railo 上的 cfml 中工作。