身份验证
OAuth 2.0不使用长久有效令牌而使用短时有效令牌来提供长期用户认证(通过刷新令牌)。刷新令牌允许用户在一段时间内留在应用程序中而不必重新输入用户名和密码。这样可以避免用户认证数据泄露的风险。
设置OAuth 2.0通过以下方式授权:
- 通过用户名或电子邮箱和密码
- 通过社交网络
- 通过Steam
如果启用了该选项,则用户注册和认证通过调用Awake
方法。该方法将检查当前刷新令牌的有效期。
要配置OAuth 2.0授权:
- 在发布商帐户中为登录管理器项目设置OAuth 2.0认证。
- 在Unity项目中设置资源。
在发布商帐户中设置登录管理器项目的OAuth 2.0认证
- 前往您的发布商帐户。
- 在侧边栏中单击登录管理器。
- 在登录管理器项目窗格中单击配置。
- 前往安全性区块,然后选择OAuth 2.0部分。
- 单击添加OAuth 2.0。
- 指定OAuth 2.0重定向URI,然后单击连接。
- 复制并保存客户端ID。
在Unity项目中设置资源
- 前往您的Unity项目。
- 在主菜单中单击
Window > Xsolla > Edit Settings 。 - 在
Inspector 面板中:- 在
Authorization method 字段中,选择OAuth2.0 。 - 在
OAuth2.0 client ID 字段中,指定在发布商帐户中设置OAuth 2.0时收到的客户端ID。
- 在
Login & Account System资源中实现了以下方法与刷新令牌交互:
IsOAuthTokenRefreshInProgress
— 在刷新令牌过程中返回true
,否则为false。ExchangeCodeToToken
— 用用户的认证代码换取一个有效的JWT。
GetSocialNetworkAuthUrl
方法中的oauthState
参数用于OAuth 2.0认证过程中的额外用户验证。该参数用于防止可能的CSRF攻击。
仅在使用以下资源时参考本方法详解:
- Game Commerce
- Cross-Buy
Cross-Buy资源将于2022年4月淘汰。您可以继续使用该资源,但它将不再更新及补充新功能。建议您转移到Game Commerce资源,该资源包含配合艾克索拉产品使用的所有类和方法。
您可以将Game Commerce和Cross-Buy资源与您的自有登录系统集成。要进行该操作,请通过支付中心访问令牌在您的应用程序中实现用户身份认证。
使用自有授权系统与艾克索拉服务器的交互过程:
- 您的客户端向您的服务器发送认证请求。
- 您的服务器授权用户并向艾克索拉服务器发送请求以接收支付中心访问令牌。
- 艾克索拉服务器返回支付中心访问令牌。
- 您的服务器将支付中心访问令牌传给客户端。
- SDK方法将收到的支付中心访问令牌用作授权令牌以打开游戏内商店、进行支付及管理物品库。
获取支付中心访问令牌
在应用程序后端,请实现通过HTTP POST请求来获取支付中心访问令牌的方法。
艾克索拉API使用基本HTTP认证。请求必须包含Authorization: Basic <your_authorization_basic_key>
头,其中<your_authorization_basic_key>
是按照Base64标准加密的merchant_id:api_key
。您可以在发布商帐户中找到参数值:
- 要查找
merchant_id
,请前往项目设置 > Webhooks > 商户ID部分。 - 要查找
api_key
,请前往公司设置 > API密钥部分。
HTTP请求:
http
- http
- curl
- php
- C#
- python
- ruby
- java
- javascript
POST https://api.xsolla.com/merchant/v2/merchants/{merchant_id}/token
Headers:
Authorization: Basic <your_authorization_basic_key>
Content-Type: application/json
Body:
{
"purchase": {
"virtual_currency": {
"quantity": 100
},
"virtual_items": {
"items": [
{
"amount": 1,
"sku": "SKU01"
}
]
}
},
"settings": {
"currency": "USD",
"language": "en",
"project_id": 16184,
"ui": {
"components": {
"virtual_currency": {
"custom_amount": true
}
},
"desktop": {
"virtual_item_list": {
"button_with_price": true,
"layout": "list"
}
},
"size": "medium"
}
},
"user": {
"country": {
"allow_modify": true,
"value": "US"
},
"age": 19,
"email": {
"value": "john.smith@mail.com"
},
"id": {
"value": "user_2"
},
"name": {
"value": "John Smith"
}
}
}
curl --request POST \
--url https://api.xsolla.com/merchant/v2/merchants/{merchant_id}/token \
--header 'authorization: Basic <your_authorization_basic_key>' \
--header 'content-type: application/json' \
--data '{"user":{"id":{"value":"user_2"},"name":{"value":"John Smith"},"age":19,"email":{"value":"john.smith@mail.com"},"country":{"value":"US","allow_modify":true}},"settings":{"project_id":16184,"currency":"USD","language":"en","ui":{"size":"medium","desktop":{"virtual_item_list":{"layout":"list","button_with_price":true}},"components":{"virtual_currency":{"custom_amount":true}}}},"purchase":{"virtual_currency":{"quantity":100},"virtual_items":{"items":[{"sku":"SKU01","amount":1}]}}}'
<?php
$client = new http\Client;
$request = new http\Client\Request;
$body = new http\Message\Body;
$body->append('{"user":{"id":{"value":"user_2"},"name":{"value":"John Smith"},"age":19,"email":{"value":"john.smith@mail.com"},"country":{"value":"US","allow_modify":true}},"settings":{"project_id":16184,"currency":"USD","language":"en","ui":{"size":"medium","desktop":{"virtual_item_list":{"layout":"list","button_with_price":true}},"components":{"virtual_currency":{"custom_amount":true}}}},"purchase":{"virtual_currency":{"quantity":100},"virtual_items":{"items":[{"sku":"SKU01","amount":1}]}}}');
$request->setRequestUrl('https://api.xsolla.com/merchant/v2/merchants/{merchant_id}/token');
$request->setRequestMethod('POST');
$request->setBody($body);
$request->setHeaders(array(
'authorization' => 'Basic <your_authorization_basic_key>',
'content-type' => 'application/json'
));
$client->enqueue($request)->send();
$response = $client->getResponse();
echo $response->getBody();
var client = new RestClient("https://api.xsolla.com/merchant/v2/merchants/{merchant_id}/token");
var request = new RestRequest(Method.POST);
request.AddHeader("authorization", "Basic <your_authorization_basic_key>");
request.AddHeader("content-type", "application/json");
request.AddParameter("application/json", "{\"user\":{\"id\":{\"value\":\"user_2\"},\"name\":{\"value\":\"John Smith\"},\"age\":19,\"email\":{\"value\":\"john.smith@mail.com\"},\"country\":{\"value\":\"US\",\"allow_modify\":true}},\"settings\":{\"project_id\":16184,\"currency\":\"USD\",\"language\":\"en\",\"ui\":{\"size\":\"medium\",\"desktop\":{\"virtual_item_list\":{\"layout\":\"list\",\"button_with_price\":true}},\"components\":{\"virtual_currency\":{\"custom_amount\":true}}}},\"purchase\":{\"virtual_currency\":{\"quantity\":100},\"virtual_items\":{\"items\":[{\"sku\":\"SKU01\",\"amount\":1}]}}}", ParameterType.RequestBody);
IRestResponse response = client.Execute(request);
import http.client
conn = http.client.HTTPSConnection("api.xsolla.com")
payload = "{\"user\":{\"id\":{\"value\":\"user_2\"},\"name\":{\"value\":\"John Smith\"},\"age\":19,\"email\":{\"value\":\"john.smith@mail.com\"},\"country\":{\"value\":\"US\",\"allow_modify\":true}},\"settings\":{\"project_id\":16184,\"currency\":\"USD\",\"language\":\"en\",\"ui\":{\"size\":\"medium\",\"desktop\":{\"virtual_item_list\":{\"layout\":\"list\",\"button_with_price\":true}},\"components\":{\"virtual_currency\":{\"custom_amount\":true}}}},\"purchase\":{\"virtual_currency\":{\"quantity\":100},\"virtual_items\":{\"items\":[{\"sku\":\"SKU01\",\"amount\":1}]}}}"
headers = {
'content-type': "application/json",
'authorization': "Basic <your_authorization_basic_key>"
}
conn.request("POST", "/merchant/v2/merchants/{merchant_id}/token", payload, headers)
res = conn.getresponse()
data = res.read()
print(data.decode("utf-8"))
require 'uri'
require 'net/http'
url = URI("https://api.xsolla.com/merchant/v2/merchants/{merchant_id}/token")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
http.verify_mode = OpenSSL::SSL::VERIFY_NONE
request = Net::HTTP::Post.new(url)
request["content-type"] = 'application/json'
request["authorization"] = 'Basic <your_authorization_basic_key>'
request.body = "{\"user\":{\"id\":{\"value\":\"user_2\"},\"name\":{\"value\":\"John Smith\"},\"age\":19,\"email\":{\"value\":\"john.smith@mail.com\"},\"country\":{\"value\":\"US\",\"allow_modify\":true}},\"settings\":{\"project_id\":16184,\"currency\":\"USD\",\"language\":\"en\",\"ui\":{\"size\":\"medium\",\"desktop\":{\"virtual_item_list\":{\"layout\":\"list\",\"button_with_price\":true}},\"components\":{\"virtual_currency\":{\"custom_amount\":true}}}},\"purchase\":{\"virtual_currency\":{\"quantity\":100},\"virtual_items\":{\"items\":[{\"sku\":\"SKU01\",\"amount\":1}]}}}"
response = http.request(request)
puts response.read_body
OkHttpClient client = new OkHttpClient();
MediaType mediaType = MediaType.parse("application/json");
RequestBody body = RequestBody.create(mediaType, "{\"user\":{\"id\":{\"value\":\"user_2\"},\"name\":{\"value\":\"John Smith\"},\"age\":19,\"email\":{\"value\":\"john.smith@mail.com\"},\"country\":{\"value\":\"US\",\"allow_modify\":true}},\"settings\":{\"project_id\":16184,\"currency\":\"USD\",\"language\":\"en\",\"ui\":{\"size\":\"medium\",\"desktop\":{\"virtual_item_list\":{\"layout\":\"list\",\"button_with_price\":true}},\"components\":{\"virtual_currency\":{\"custom_amount\":true}}}},\"purchase\":{\"virtual_currency\":{\"quantity\":100},\"virtual_items\":{\"items\":[{\"sku\":\"SKU01\",\"amount\":1}]}}}");
Request request = new Request.Builder()
.url("https://api.xsolla.com/merchant/v2/merchants/{merchant_id}/token")
.post(body)
.addHeader("content-type", "application/json")
.addHeader("authorization", "Basic <your_authorization_basic_key>")
.build();
Response response = client.newCall(request).execute();
var data = JSON.stringify({
"user": {
"id": {
"value": "user_2"
},
"name": {
"value": "John Smith"
},
"age": 19,
"email": {
"value": "john.smith@mail.com"
},
"country": {
"value": "US",
"allow_modify": true
}
},
"settings": {
"project_id": 16184,
"currency": "USD",
"language": "en",
"ui": {
"size": "medium",
"desktop": {
"virtual_item_list": {
"layout": "list",
"button_with_price": true
}
},
"components": {
"virtual_currency": {
"custom_amount": true
}
}
}
},
"purchase": {
"virtual_currency": {
"quantity": 100
},
"virtual_items": {
"items": [
{
"sku": "SKU01",
"amount": 1
}
]
}
}
});
var xhr = new XMLHttpRequest();
xhr.withCredentials = true;
xhr.addEventListener("readystatechange", function () {
if (this.readyState === this.DONE) {
console.log(this.responseText);
}
});
xhr.open("POST", "https://api.xsolla.com/merchant/v2/merchants/{merchant_id}/token");
xhr.setRequestHeader("content-type", "application/json");
xhr.setRequestHeader("authorization", "Basic <your_authorization_basic_key>");
xhr.send(data);
要获取令牌,请将以下参数传入请求正文:
参数 | 类型 | 描述 |
---|---|---|
settings | object | 带有自定义项目设置的对象。 |
settings.project_id | integer | 游戏的艾克索拉ID。可在发布商帐户中项目名称的旁边找到。 必需。 |
user | object | 带用户相关数据的对象。 |
user.id | object | 授权系统中的用户ID(对象)。 |
user.id.value | string | 用户ID。 必需。 |
user.email | object | 用户邮箱(对象)。 |
user.email.value | string | 用户电子邮箱。必须符合RFC 822协议标准。 必需。 |
user.name | object | 带有用户昵称相关数据的对象。必需。 |
user.name.value | string | 用户昵称。 |
user.steam_id | object | 用户Steam ID(对象)。 |
user.steam_id.value | string | 用户Steam ID。如应用程序在Steam上发布,则为必需。 |
user.playfab_id | object | 用户PlayFab ID(对象)。 |
user.playfab_id.value | string | 用户PlayFab ID。如果应用程序使用PlayFab服务来发放商品,则为必需。 |
请求和响应示例见API参考。
custom_parameters
、purchase
等),它们不能用来接收授权令牌。使用用户JWT
要使用支付中心访问令牌来打开游戏内商店,进行支付及管理物品库,请将令牌传入SDK方法中的XsollaLogin.Instance.Token
和XsollaStore.Instance.Token
属性。
授权令牌的使用示例请参见教程:
实现令牌过期后重新获取支付中心访问令牌的逻辑。建议在后台获取新令牌,这样用户就无须重新登录应用程序。
本机用户认证可以让用户通过其移动设备上配置的社交网络帐户来登录您的应用程序。
用户首次登录时,社交网络应用程序将启动并询问是否允许进行用户认证。允许后,未来的认证将自动进行,无需用户执行任何操作。
目前SDK已实现通过以下社交网络进行本机用户认证:
- 微信
要配置本机用户认证:
- 创建适用于Android的Unity项目编译版本。
- 在社交网络的开发者帐户中配置应用程序:
为Android创建Unity项目编译版本
- 前往您的Unity项目。
- 在主菜单中单击
File > Build settings 。 - 在
Platform 面板中单击Android 。 - 单击
Build 。 - 确保生成了散列密钥:
- 在主菜单中单击
Window > Xsolla > Edit Settings 。 - 确保
Android debug hash key 字段显示散列密钥。
- 在主菜单中单击
在接下来的本机用户认证配置中需用到:
- 在
File > Build settings 中选择Android平台后在Inspector 面板中找到的Package Name 。 - 在
Window > Xsolla > Edit Settings > Inspector > Android class name 中找到的Android class name 。 - 在
Window > Xsolla > Edit Settings > Inspector > Android debug hash key 中找到的Android debug hash key 。
在Facebook开发者帐户中设置应用页面
- 前往Facebook开发者帐户中的项目设置。
- 前往设置 > 基本。
- 单击添加平台,选择Android。
- 在Google Play包名称字段中指定Unity项目中的
Package Name 。 - 在类名字段中指定Unity项目的
Android class name 。 - 在密钥散列字段中指定Unity项目的
Android debug hash key 。 - 单击保存更改。
在接下来的本机用户认证配置中,还会用到设置 > 基本部分中的应用编号和应用密钥。
在Google API Console中设置项目
- 前往Google API Console。
- 单击新建项目。
- 指定项目名称和位置,然后单击保存。
- 前往所创建的项目,然后单击侧边栏上的OAuth同意屏幕。
- 选择外部,然后单击创建。
- 指定必需参数,然后单击保存。
- 在侧边栏上点击凭据。
- 为您的Unity应用程序创建一个OAuth 2.0客户端:
- 单击创建凭据,选择OAuth客户端ID。
- 在应用类型字段中指定Android。
- 指定名称。
- 在包名称字段中指定您Unity应用程序的
Package Name 。 - 在SHA-1证书指纹字段中指定您Unity应用程序的
Android debug hash key 。 - 单击创建。
- 单击确定。
- 为Web应用创建一个OAuth 2.0客户端:
- 单击创建凭据,选择OAuth客户端ID。
- 在应用类型字段中指定Web应用。
- 指定名称。
- 在已获授权的重定向URI部分单击添加URI,并指定
https://login.xsolla.com/api/social/oauth2/callback
URI。 - 单击创建。
- 单击确定。
在接下来的本机用户认证配置中,还会用到Web应用的客户端ID设置中的客户端ID和客户端密钥。
在艾克索拉发布商帐户中设置登录管理器项目的社交网络连接
- 在发布商帐户中打开您的项目。
- 在侧边栏中单击登录管理器,然后前往登录管理器项目 > 您的登录管理器项目 > 社交网络连接。
- 要设置通过Facebook进行认证:
- 在Facebook面板中单击编辑,将状态更改为断开连接。
- 在Application ID字段中指定Facebook开发者帐户中的应用编号。
- 在Application Secret字段中指定Facebook开发者帐户中的应用密钥。
- 单击连接。
- 要设置通过Google进行认证:
- 在Google面板中单击编辑,将状态更改为断开连接。
- 在Application ID字段中指定Google API Console中Web应用的客户端ID。
- 在Application Secret字段中指定Google API Console中Web应用的客户端密钥。
- 单击连接。
为Unity项目设置资源
- 前往您的Unity项目。
- 在主菜单中单击
Window > Xsolla > Edit Settings 。 - 指定应用程序ID:
- 在
Facebook App ID 字段中指定Facebook开发者帐户中的应用编号。 - 在
Google server ID 字段中指定Google API Console中的Web应用的客户端ID。 - 在
WeChat App ID 中指定微信应用设置中的AppID。 - 在
QQ App ID 中指定QQ应用设置中的AppID。
- 在
本机用户认证可让玩家通过其所装的Steam应用程序进入您的应用程序。
要设置本机用户认证:
配置您的Unity项目
- 手动创建一个
steam_appid.txt
文件并在其中输入您在Steam中的应用ID。然后将该文件放在项目的Assets
目录下。
Assets
目录中找到该steam_appid.txt
文件。该文件包含一个演示项目的Steam应用ID。- 打开您的Unity项目。
- 在主菜单中,前往
Window > Xsolla > Edit Settings 。 - 在
Inspector 面板:- 勾选
Use Steam authorization 复选框。 - 在
Steam App ID 字段中,指定您在Steam中的应用ID。该值应与steam_appid.txt
文件中的值相同。
- 勾选
配置事件处理
要通过Steam认证用户,应使用SteamAuth
方法获取session ticket
。然后在调用RequestTokenBy
方法时传入收到的值。随后即可获得调用API时需使用的令牌。
确保通过Steam进行认证
- 创建适用于独立平台的Unity项目的编译文件。
- 启动Steam并登录。
- 启动您的应用程序。如果一切正确,将显示Steam弹出窗口。
令牌失效可提高应用程序中用户认证数据的安全性。如启用该选项,每次用户认证时旧令牌将失效,新令牌将取代旧令牌。
使用SDK时,如果with_logout
参数值为1
,调用
要在您的Unity项目中启用令牌失效:
- 在主菜单中,前往
Window > Xsolla > Edit Settings 。 - 在
Inspector 面板中,勾选Enable JWT invalidation 复选框。
您可以使用艾克索拉启动器向用户交付应用程序及其更新。启动器包含一个内置的授权工具。如要避免重复输入用户名和密码的需要,可设置通过启动器授权进入应用程序。
设置SDK与启动器配合工作
- 在您的发布商帐户中设置启动器。
config.json
文件中,请更改以下对象的值:launcher_project_id
— 指定在发布商帐户 > 启动器 > 常规设置 > 常规信息中找到的启动器IDlogin_project_id
— 指定发布商帐户 > 启动器 > 常规设置 > 验证中找到的登录管理器ID
- 在您的应用程序中实现启动器授权逻辑。
- 生成启动器安装文件和编译版本压缩包。
- 创建应用程序编译版本。
- 将应用程序编译版本上传至艾克索拉更新服务器。
实现通过启动器进行身份认证的逻辑
通过启动器在应用程序中进行授权的过程如下:
- 用户授权进入启动器。
- 用户安装并运行应用程序。
- 启动器运行该应用程序并通过命令行传入用户参数。授权令牌在
xsolla-login-token
参数中传递。 - 应用程序处理命令行参数并获取令牌。您可在演示项目中查看令牌处理脚本示例。
- 应用程序验证收到的令牌。您可在演示项目中查看令牌验证脚本示例。
- 应用程序在不显示授权页面的情况下自动完成用户授权。您可在演示项目中查看用户授权脚本。
XsollaLogin.Instance.Token
和XsollaStore.Instance.Token
属性。创建应用程序编译版本
- 前往您的Unity项目。
- 在主菜单中单击
Window > Xsolla > Edit Settings 。在Inspector 面板中:- 在
Project ID 字段中指定在发布商帐户 > 项目设置 > 项目ID中找到的项目ID。 - 在
Login ID 字段中指定在发布商帐户 > 启动器 > 常规设置 > 验证中找到的登录管理器ID。
- 在
- 运行授权场景,令牌在其中得到处理。
- 在主菜单中单击
File > Build settings ,然后单击Add Open Scenes 。确保授权场景添加为列表首项。 - 单击
Build 。 - 在弹出窗口中指定放置所得编译版本的目录路径。
设备ID认证能让用户在无需输入注册数据的情况下在移动设备上使用应用程序。用户首次使用设备ID登录应用程序时将自动创建一个新帐户,用户无需输入用户名、邮箱地址或其他数据。
您可以通过设备ID在后台模式下实现用户在一个或多个移动设备上的身份认证。要使用该功能,用户需将设备ID与现有帐户关联。
SDK支持在Android和iOS设备上通过移动设备的ID进行用户认证。
获取设备ID
设备ID由平台生成并可供该移动设备上安装的应用程序使用。SDK使用平台API获取ID值并使用该值通过艾克索拉API执行多种功能。
iOS设备ID在UIDevice.identifierForVendor属性中传递。使用标准Unity方法SystemInfo.deviceUniqueIdentifier来判断该ID。
Android设备ID在android.provider.Settings.Secure.ANDROID_ID常量中传递。SDK使用自己的逻辑来判断该ID,因为标准Unity方法以MD5散列的形式返回Android设备ID,不适用于艾克索拉API调用。
SDK方法
SDK实现以下功能的方法:
身份验证
SDK方法名称 | 描述 |
---|---|
AuthViaDeviceID | 使用当前设备ID认证用户进入应用程序。 |
帐户升级
SDK方法名称 | 描述 |
---|---|
AddUsernameEmailAuthToAccount | 添加可用于身份认证的用户名、邮箱地址和密码到当前帐户。 |
LinkSocialProvider | 将可用于身份认证的社交网络关联至当前帐户。 |
设备管理
SDK方法名称 | 描述 |
---|---|
GetUserDevices | 返回与当前用户帐户关联的设备的列表。 |
LinkDeviceToAccount | 将指定设备关联至当前用户帐户。 |
UnlinkDeviceFromAccount | 取消指定设备与当前用户帐户的关联。 |
发现了错别字或其他内容错误? 请选择文本,然后按Ctrl+Enter。