# Code-Link

> Provide a Code Link sign-in option to enable account linking by sharing unique codes between devices.

###### SDK 最低版本：3.0.0##minimum-sdk-version-300

请查看以下场景，为您游戏中使用 Code-Link 的玩家设置身份验证：

* 设置 Code-Link。
* 使用 Code-Link 登录。

## 设置 Code-Link##set-up-code-link

1. 将 Unity Authentication 中的 ID 提供商设置为 Code-Link：
   1. 在 Unity 编辑器菜单中，转到 **Edit（编辑）**> **Project Settings...（项目设置...）**，然后选择 **Services（服务）**> **Authentication（身份验证）**。
   2. 将 **ID Providers（ID 提供商）** 设置为 **Code-Link**，然后选择 **Add（添加）**。
   3. 选择 **Save（保存）**。

## 使用 Code-Link 登录##sign-in-using-code-link

使用以下 Code-Link 功能来以玩家身份登录：

1. 玩家以匿名方式或使用任意受支持的 ID 提供商登录设备 A。
2. 玩家决定在设备 B（尚未登录）使用相同的帐户，并让设备 B 生成登录代码。
3. 收到登录代码后，玩家在设备 A 上输入该代码来确认该代码已获授权。
4. 玩家返回设备 B 并请求使用代码登录。
5. 设备 B 使用与设备 A 上相同的帐户完成身份验证。


**Frame:**
![](/api/media?file=/authentication/media/images/code-link-player-flow-diagram.jpg)


**Frame:**
![](/api/media?file=/authentication/media/images/code-link-sign-in.jpg)


**Frame:**
![](/api/media?file=/authentication/media/images/code-link-code-confirmation.jpg)

> **Note:**
>
> **注意**：如果设备 B 会轮询服务，直到代码得到确认或到期，则可以跳过步骤 4。


**Frame:**
![](/api/media?file=/authentication/media/images/code-link-sign-in-polling.jpg)

要使用 Code-Link 登录，请按照以下步骤操作：

1. 从要进行身份验证的未认证设备使用 `GenerateSignInCodeAsync` 方法（回传标识符非必选项，但推荐使用该操作来识别生成登录代码的设备）生成**登录代码**。

2. 向玩家显示生成的 SignInCode 和过期时间。

   > **Note:**
   >
   > **注意**：**标识符**的最大长度为 128 个字符。

   ```cs
   async Task GenerateCodeAsync(string identifier)
   {
       try
       {
           var codeInfo = await AuthenticationService.Instance.GenerateSignInCodeAsync(identifier);
           // Display code, and expiration and identifier to the player
       }
       catch (Exception e)
       {
           // Notify the client something went wrong generating the code
       }
   }
   ```

3. 让玩家可以在另一台已经过身份验证的设备上输入该 SignInCode。

4. （可选）通过 `GetSignInCodeInfoAsync`，使用玩家提供的 SignInCode 来获取 SignInCode 信息，并向玩家显示该信息，以便玩家比较两台设备上的标识符，以此确认是否在为正确的设备授权。

5. 通过 `ConfirmCodeAsync` 授权 Code-Link 登录。
   > **Note:**
   >
   > **注意**：`ConfirmCodeAsync` 方法还支持在 **idProvider** 和 **externalToken** 中使用可选的参数。这些参数只应在控制台中使用，如果从控制台客户端使用，则会返回错误。
   ```cs
   async Task GetCodeInfoAsync(string signInCode)
   {
       try
       {
           var codeInfo = await AuthenticationService.Instance.GetSignInCodeInfoAsync(signInCode);
           // Display code, and expiration and identifier to the player and ask them to authorize the code-link sign in
       }
       catch (Exception e)
       {
           // Notify the client something went wrong getting the code information
       }
   }

   async Task ConfirmCodeAsync(string signInCode)
   {
   try
   {
   await AuthenticationService.Instance.ConfirmCodeAsync(signInCode);
   // Display a confirmation that the device should be authorized
   }
   catch (Exception e)
   {
   // Notify the client something went wrong with the code confirmation
   }
   }
   ```

6. 通过调用 `SignInWithCodeAsync`，在生成 SignInCode 的同一设备上登录玩家。（用于验证 Code-Link 登录的凭据储存在内存中，因此请确保先调用 GenerateSignInCodeAsync，然后再调用 SignInWithCodeAsync，否则会抛出异常。）如果代码尚未得到授权，则此方法成功，但用户不会登录；请检查是否出现 **SignedIn** 事件，以判断登录是否成功。
   ```cs
   public async Task SignInWithCodeAsync()
   {
       try
       {
           AuthenticationService.Instance.SignedIn += UserHasSignedIn
           await AuthenticationService.Instance.SignInWithCodeAsync();
       }
       catch (Exception e)
       {
           // Notify the client something went wrong signing in the player
       }
       finally
       {
           AuthenticationService.Instance.SignedIn -= UserHasSignedIn
       }
   }

   public void UserHasSignedIn() {
       // Notify the client the user signed in successfully.
   }
   ```

````text
<Note>
**注意**：`SignInWithCodeAsync` 方法还支持自动轮询（每 5 秒钟轮询一次），因此设备会在该代码获得授权后自动使玩家登录，如果代码已过期，则会抛出异常。此方法还接受 `CancellationToken` 取消轮询。
```cs
CancellationTokenSource CodeLinkCancellationTokenSource;
</Note>

public async Task PollSignInWithCodeAsync()
\{
    try
    \{
        CodeLinkCancellationTokenSource = new CancellationTokenSource();
        await AuthenticationService.SignInWithCodeAsync(true, CodeLinkCancellationTokenSource.Token);
    }
    catch (Exception e)
    \{
        // Notify the client something went wrong with Polling for Code Confirmation
    }
}

public void CancelSignInWithCode()
\{
    CodeLinkCancellationTokenSource.Cancel();
}
````

```text
```
