> ## Documentation Index
> Fetch the complete documentation index at: https://devdocs.xbox.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Configurer l'authentification PlayFab avec des applications UWP

> Tutoriel pas à pas pour ajouter l'authentification PlayFab à une application de plateforme Windows universelle à l'aide de Windows Hello pour la création de compte et la connexion des joueurs.

Ce tutoriel vous guide à travers la procédure d'authentification PlayFab avec la plateforme Windows universelle (UWP).

<Info>
  Cette procédure constitue une introduction de base sur la façon d'obtenir toutes les entités et d'effectuer l'authentification via Windows Hello et PlayFab. Pour un exemple plus élaboré d'authentification Windows Hello et PlayFab, consultez notre `[UWPExample project](https://github.com/PlayFab/UWPExample)`.
</Info>

## Configuration requise

* Suivez le [guide MSDN « Get Set Up »](https://learn.microsoft.com/en-us/windows/apps/windows-app-sdk/set-up-your-development-environment) pour préparer Windows et Visual Studio au développement UWP.
* Disposer d'un titre [PlayFab](https://developer.playfab.com/) inscrit.
* Avoir une bonne connaissance des [principes de base et bonnes pratiques de connexion](/fr/services/playfab/identity/player-identity/login/login-basics-best-practices).

<Note>
  Il est *très* important d'utiliser le système d'exploitation Windows 10, d'être connecté avec un compte Microsoft vérifié et d'avoir configuré une interface d'accès telle qu'un code PIN. Si ces conditions ne sont pas\* remplies, l'application échouera sans aucune explication utile.
</Note>

## Préparation d'un projet Visual Studio

Démarrez Visual Studio et créez un nouveau projet.

1. Sous **Templates**, sélectionnez **Windows Universal**.
2. Sélectionnez ensuite le type **Blank App (Universal Windows)**.
3. Nommez-le **GettingStartedPlayfabUWP**.
4. Sélectionnez le bouton **OK** pour valider.

<img src="https://mintcdn.com/microsoft-4404708b/3hg2JQs0m7qmDqay/images/playfab/identity/player-identity/platform-specific-authentication/tutorials/uwp/vs-new-uwp-app.png?fit=max&auto=format&n=3hg2JQs0m7qmDqay&q=85&s=bc3649ba465e5a2c28f25c704618d402" alt="Visual Studio : nouvelle application UWP vide" width="941" height="653" data-path="images/playfab/identity/player-identity/platform-specific-authentication/tutorials/uwp/vs-new-uwp-app.png" />

1. Sélectionnez la **Target Version** et la **Minimum Version** correspondant à votre **Project**.
2. Sélectionnez le bouton **OK**.

<img src="https://mintcdn.com/microsoft-4404708b/3hg2JQs0m7qmDqay/images/playfab/identity/player-identity/platform-specific-authentication/tutorials/uwp/vs-uwp-sdk-version.png?fit=max&auto=format&n=3hg2JQs0m7qmDqay&q=85&s=415a4b78488216200bab8bb492386fb6" alt="Visual Studio : version du SDK UWP" width="609" height="218" data-path="images/playfab/identity/player-identity/platform-specific-authentication/tutorials/uwp/vs-uwp-sdk-version.png" />

Une fois le **Project** créé, ajoutez le **PlayFab SDK** à l'aide du **NuGet Package Manager**.

1. Sélectionnez d'abord l'onglet **Tools**.
2. Dans le menu déroulant, sélectionnez **NuGet Package Manager**.
3. Sélectionnez ensuite **Manage NuGet Packages for Solution**.

<img src="https://mintcdn.com/microsoft-4404708b/3hg2JQs0m7qmDqay/images/playfab/identity/player-identity/platform-specific-authentication/tutorials/uwp/vs-nuget-package-manager.png?fit=max&auto=format&n=3hg2JQs0m7qmDqay&q=85&s=d14dc0d92b7e125410a7bbd4aa6758a4" alt="Visual Studio : NuGet Package Manager" width="799" height="551" data-path="images/playfab/identity/player-identity/platform-specific-authentication/tutorials/uwp/vs-nuget-package-manager.png" />

Dans la fenêtre **NuGet Manager** :

1. Sélectionnez **Browse** et recherchez le package **PlayFabAllSDK**.
2. Sélectionnez votre **Project** cible.
3. Sélectionnez ensuite le bouton **Install**.

<img src="https://mintcdn.com/microsoft-4404708b/3hg2JQs0m7qmDqay/images/playfab/identity/player-identity/platform-specific-authentication/tutorials/uwp/vs-install-playfab-sdk.png?fit=max&auto=format&n=3hg2JQs0m7qmDqay&q=85&s=daf9990bd337b14080d4a96eb1a73617" alt="Visual Studio : installer le SDK PlayFab" width="1022" height="568" data-path="images/playfab/identity/player-identity/platform-specific-authentication/tutorials/uwp/vs-install-playfab-sdk.png" />

Une fois cette opération terminée, la configuration de base de votre projet est achevée. Dans la section suivante, nous allons modifier deux classes qui doivent être générées automatiquement lors de la création du projet :

1. **App**
2. **MainPage**

## Implémentation

### App.xaml.cs

Cette classe se contente de configurer notre SDK PlayFab en définissant un ID de titre approprié. N'oubliez pas de remplacer l'ID de titre par le vôtre.

```csharp theme={null}
using System;
using Windows.ApplicationModel;
using Windows.ApplicationModel.Activation;
using Windows.UI.Xaml;
using Windows.UI.Xaml.Controls;
using Windows.UI.Xaml.Navigation;

namespace GettingStartedPlayfabUWP
{
    // This class is generated upon project creation.
    // While template on it's own contains a lot of xml comments, we are only interested in lines 17 and 27
    sealed partial class App : Application
    {

        // Replace PLAYFAB_TITLE_ID with your own
        public const string PlayfabTitleId = "PLAYFAB_TITLE_ID";

        /// <summary>
        /// Initializes the singleton application object. This is the first line of authored code
        /// executed, and as such is the logical equivalent of main() or WinMain().
        /// </summary>
        public App()
        {

            // This is the only line of functional code we need to add to this class.
            PlayFab.PlayFabSettings.TitleId = PlayfabTitleId;

            this.InitializeComponent();
            this.Suspending += OnSuspending;
        }

        /// <summary>
        /// Invoked when the application is launched normally by the end user. Other entry points
        /// will be used such as when the application is launched to open a specific file.
        /// </summary>
        /// <param name="e">Details about the launch request and process.</param>
        protected override void OnLaunched(LaunchActivatedEventArgs e)
        {
            Frame rootFrame = Window.Current.Content as Frame;

            // Do not repeat app initialization when the Window already has content,
            // just ensure that the window is active
            if (rootFrame == null)
            {
                // Create a Frame to act as the navigation context and navigate to the first page
                rootFrame = new Frame();

                rootFrame.NavigationFailed += OnNavigationFailed;

                if (e.PreviousExecutionState == ApplicationExecutionState.Terminated)
                {
                    //TODO: Load state from previously suspended application
                }

                // Place the frame in the current Window
                Window.Current.Content = rootFrame;
            }

            if (e.PrelaunchActivated == false)
            {
                if (rootFrame.Content == null)
                {
                    // When the navigation stack isn't restored navigate to the first page,
                    // configuring the new page by passing required information as a navigation
                    // parameter
                    rootFrame.Navigate(typeof(MainPage), e.Arguments);
                }
                // Ensure the current window is active
                Window.Current.Activate();
            }
        }

        /// <summary>
        /// Invoked when Navigation to a certain page fails
        /// </summary>
        /// <param name="sender">The Frame which failed navigation</param>
        /// <param name="e">Details about the navigation failure</param>
        void OnNavigationFailed(object sender, NavigationFailedEventArgs e)
        {
            throw new Exception("Failed to load Page " + e.SourcePageType.FullName);
        }

        /// <summary>
        /// Invoked when application execution is being suspended. Application state is saved
        /// without knowing whether the application will be terminated or resumed with the contents
        /// of memory still intact.
        /// </summary>
        /// <param name="sender">The source of the suspend request.</param>
        /// <param name="e">Details about the suspend request.</param>
        private void OnSuspending(object sender, SuspendingEventArgs e)
        {
            var deferral = e.SuspendingOperation.GetDeferral();
            //TODO: Save application state and stop any background activity
            deferral.Complete();
        }
    }
}
```

### MainPage.xaml

Ce fichier contient la disposition de notre page principale. Il s'agit d'une disposition *très simple* composée de deux boutons et d'un champ de saisie de texte regroupés dans une grille orientée verticalement.

Les boutons sont liés à des méthodes spécifiques, et la zone de texte est accessible par son nom `UsernameInput`.

```xaml theme={null}
<Page
    x:Class="GettingStartedPlayfabUWP.MainPage"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:local="using:GettingStartedPlayfabUWP"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    mc:Ignorable="d">

    <Grid Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
        <StackPanel Margin="0,10,10,0">
            <TextBox x:Name="UsernameInput" TextWrapping="Wrap" Text="" PlaceholderText="Username..."/>
            <Button x:Name="RegisterButton" Content="Register With Hello" HorizontalAlignment="Stretch" VerticalAlignment="Stretch" Click="RegisterRequest"/>
            <Button x:Name="LoginButton" Content="Sign In With Hello" HorizontalAlignment="Stretch" VerticalAlignment="Stretch" Click="LogInRequest"/>
        </StackPanel>
    </Grid>
</Page>
```

### MainPage.xaml.cs

Il s'agit de la classe fonctionnelle de la page principale, qui constitue le cœur de l'exemple. Reportez-vous aux commentaires du code et examinez les différentes méthodes conçues pour vous guider dans l'inscription et la connexion PlayFab+Hello.

La façon la plus simple de commencer à comprendre le code est d'examiner les méthodes déclenchées par les boutons correspondants :

* **RegisterRequest**
* **LogInRequest**.

```csharp theme={null}
using System;
using System.Linq;
using System.Threading.Tasks;
using Windows.Foundation;
using Windows.Networking.Connectivity;
using Windows.Security.Credentials;
using Windows.Security.Cryptography;
using Windows.Security.Cryptography.Core;
using Windows.Storage.Streams;
using Windows.UI.Popups;
using Windows.UI.Xaml;
using Windows.UI.Xaml.Controls;
using PlayFab;
using PlayFab.ClientModels;

namespace GettingStartedPlayfabUWP
{
    public sealed partial class MainPage : Page
    {
        // Shortcut to get current value of UsernameInput
        public string Username => UsernameInput.Text;

        public MainPage()
        {
            this.InitializeComponent();
        }

        /// <summary>
        /// This method is invoked when you select the Register button
        /// This method illustrates the flow for Registration process.
        /// We operate on 2 entities:
        /// - User Credentials of type KeyCredential
        /// - Public Key of type String
        /// We first check if user with this id already has Credentials. If so, we redirect to login procedure.
        /// Then we create new User Credentials. Check CreateKeyCredential for implementation details
        /// Then we get Base64 encoded Public Key using the new User Credentials. Check GetPublicKeyBase64 for implementation details
        /// Then we execute RegisterWithHello api call call. Check CallPlayFabRegisterWithHello for implementation details
        /// </summary>
        private async void RegisterRequest(object sender, RoutedEventArgs e)
        {
            // Check if the user already exists and if so log them in.
            KeyCredentialRetrievalResult retrieveResult = await KeyCredentialManager.OpenAsync(Username);
            if (retrieveResult.Status == KeyCredentialStatus.Success)
            {
                // Redirect to login procedure
                LogInRequest(sender, e);
                return;
            }

            // Create a new KeyCredential for the user on the device.
            var credential = await CreateKeyCredential(Username);
            if (credential == null) return;

            var publicKey = await GetPublicKeyBase64(credential);
            if (string.IsNullOrEmpty(publicKey)) return;
            // Include the name of the current device for the benefit of the user.
            // The server could support a Web interface that shows the user all the devices they
            // have signed in from and revoke access from devices they have lost.

            var registerResponse = await CallPlayFabRegisterWithHello(publicKey, Username);

            await ShowMessage("Registered and signed in with Session Ticket " + registerResponse.Result.SessionTicket);
        }

        //
        /// <summary>
        /// This method is invoked when you select the Log In button
        /// This method shows entities flow during the sign in process.
        /// We have 4 different entities:
        /// - User Credentials of type KeyCredential
        /// - Public Key Hint of type String
        /// - Challenge of type String
        /// - SignedChallenge of type String
        ///
        /// We first acquire the User Credentials. We do it based on Username. Check GetUserCredentials method for implementation details
        /// Next, we get Public Key Hint based on those credentials. Check GetPublicKeyHint for implementation details.
        /// Next we request a Challenge from PlayFab. Check GetPlayFabHelloChallenge for implementation details
        /// Next we sign the Challenge using User Credentials, so we obtain Signed Challenge. Check GetPlayFabHelloChallenge for implementation details
        /// Finally we use Signed Challenge and Public Key Hint to log into PlayFab. Check CallPlayFabLoginWithHello for implementation details
        /// </summary>
        private async void LogInRequest(object sender, RoutedEventArgs e)
        {
            // Get credentials based on current Username.
            var credentials = await GetUserCredentials(Username);
            if (credentials == null) return;

            // Credentials will give us Public Key. We use it to construct Public Key Hint, which is first important entity for PlayFab+UWP authentication.
            var publicKeyHint = GetPublicKeyHintBase64(credentials);
            if (string.IsNullOrEmpty(publicKeyHint)) return;

            // Get PlayFab Challenge to sign for Windows Hello.
            var challenge = await GetPlayFabHelloChallenge(publicKeyHint);
            if (string.IsNullOrEmpty(challenge)) return;

            // Request user to sign the challenge.
            var signedChallenge = await RequestUserSignChallenge(credentials, challenge);
            if (string.IsNullOrEmpty(signedChallenge)) return;

            // Send the signature back to the server to confirm our identity.
            // The publicKeyHint tells the server which public key to use to verify the signature.
            var result = await CallPlayFabLoginWithHello(publicKeyHint, signedChallenge);
            if (result == null) return;

            // Report the result.
            await ShowMessage("Signed in with Session Ticket " + result.Result.SessionTicket);
        }

        public async Task<string> GetPublicKeyBase64(KeyCredential userCredential)
        {

            IBuffer publicKey = userCredential.RetrievePublicKey();

            if (publicKey == null)
            {
                await ShowMessage("Failed to get public key for credential");
                return null;
            }

            return CryptographicBuffer.EncodeToBase64String(publicKey);
        }

        public string GetPublicKeyHintBase64(KeyCredential userCredential)
        {
            HashAlgorithmProvider hashProvider = HashAlgorithmProvider.OpenAlgorithm(HashAlgorithmNames.Sha256);
            var publicKey = userCredential.RetrievePublicKey();
            IBuffer publicKeyHash = hashProvider.HashData(publicKey);
            return CryptographicBuffer.EncodeToBase64String(publicKeyHash);
        }

        public async Task<KeyCredential> GetUserCredentials(string userId)
        {
            // Open credential based on our Username and make sure it is successful
            KeyCredentialRetrievalResult retrieveResult = await KeyCredentialManager.OpenAsync(userId);

            if (retrieveResult.Status != KeyCredentialStatus.Success)
            {
                await ShowMessage("Error: Unable to open credentials! " + retrieveResult.Status);
                return null;
            }

            return retrieveResult.Credential;
        }

        public async Task<string> GetPlayFabHelloChallenge(string publicKeyHint)
        {
            // Request challenge from PlayFab and make sure response has no errors
            var challengeResponse = await PlayFab.PlayFabClientAPI.GetWindowsHelloChallengeAsync(new GetWindowsHelloChallengeRequest
            {
                PublicKeyHint = publicKeyHint,
                TitleId = PlayFab.PlayFabSettings.TitleId
            });

            if (challengeResponse.Error != null)
            {
                await ShowMessage($"Error during getting challenge: {challengeResponse.Error.Error}");
                return null;
            }

            return challengeResponse.Result.Challenge;

        }

        public async Task<string> RequestUserSignChallenge(KeyCredential credentials, string challenge)
        {
            IBuffer challengeBuffer = CryptographicBuffer.DecodeFromBase64String(challenge);
            KeyCredentialOperationResult opResult = await credentials.RequestSignAsync(challengeBuffer);

            if (opResult.Status != KeyCredentialStatus.Success)
            {
                await ShowMessage("Failed sign the challenge string: " + opResult.Status);
                return null;
            }

            return CryptographicBuffer.EncodeToBase64String(opResult.Result);
        }

        public async Task<PlayFabResult<LoginResult>> CallPlayFabLoginWithHello(string publicKeyHint, string signedChallenge)
        {
            var loginResponse = await PlayFab.PlayFabClientAPI.LoginWithWindowsHelloAsync(new LoginWithWindowsHelloRequest
            {
                ChallengeSignature = signedChallenge,
                PublicKeyHint = publicKeyHint
            });

            if (loginResponse.Error != null)
            {
                await ShowMessage($"Failed to log in: {loginResponse.Error.Error}");
                return null;
            }

            return loginResponse;
        }

        public IAsyncOperation<IUICommand> ShowMessage(string messageString)
        {
            MessageDialog message = new MessageDialog($"{messageString}");
            return message.ShowAsync();
        }

        public async Task<PlayFabResult<LoginResult>> CallPlayFabRegisterWithHello(string publicKey, string username)
        {
            var hostNames = NetworkInformation.GetHostNames();
            var localName = hostNames.FirstOrDefault(name => name.DisplayName.Contains(".local"));
            string computerName = localName.DisplayName.Replace(".local", "");

            var registerResult = await PlayFab.PlayFabClientAPI.RegisterWithWindowsHelloAsync(new RegisterWithWindowsHelloRequest
            {
                DeviceName = computerName,
                PublicKey = publicKey,
                UserName = username
            });

            if (registerResult.Error != null)
            {
                await ShowMessage(registerResult.Error.GenerateErrorReport());
                return null;
            }

            return registerResult;
        }

        public async Task<KeyCredential> CreateKeyCredential(string username)
        {
            KeyCredentialRetrievalResult keyCreationResult = await KeyCredentialManager.RequestCreateAsync(username, KeyCredentialCreationOption.ReplaceExisting);
            if (keyCreationResult.Status != KeyCredentialStatus.Success)
            {
                // User has authenticated with Windows Hello and the key credential is created.
                await ShowMessage("Failed to create key credential: " + keyCreationResult.Status);
                return null;
            }

            return keyCreationResult.Credential;
        }

    }

}
```

## Test

Pour exécuter l'application :

1. Entrez votre nom d'utilisateur.
2. Sélectionnez le bouton **Register With Hello**.

<img src="https://mintcdn.com/microsoft-4404708b/3hg2JQs0m7qmDqay/images/playfab/identity/player-identity/platform-specific-authentication/tutorials/uwp/uwp-example-register.png?fit=max&auto=format&n=3hg2JQs0m7qmDqay&q=85&s=db14681e726823d1c03c8e3dee9cde20" alt="Exemple UWP : inscription" width="502" height="353" data-path="images/playfab/identity/player-identity/platform-specific-authentication/tutorials/uwp/uwp-example-register.png" />

Suivez les instructions d'authentification proposées par **Windows**.

1. Une fois votre identité confirmée, un message de confirmation indique que le compte a été **Registered and signed in**.
2. Avec un **Session Ticket**.

<img src="https://mintcdn.com/microsoft-4404708b/3hg2JQs0m7qmDqay/images/playfab/identity/player-identity/platform-specific-authentication/tutorials/uwp/uwp-example-register-confirmation.png?fit=max&auto=format&n=3hg2JQs0m7qmDqay&q=85&s=fbfb81545c9b7b92ac7d1b0df0810398" alt="Exemple UWP : confirmation de l'inscription" width="695" height="309" data-path="images/playfab/identity/player-identity/platform-specific-authentication/tutorials/uwp/uwp-example-register-confirmation.png" />

1. Sélectionnez le bouton **Sign in With Hello**.

<img src="https://mintcdn.com/microsoft-4404708b/3hg2JQs0m7qmDqay/images/playfab/identity/player-identity/platform-specific-authentication/tutorials/uwp/uwp-example-sign-in.png?fit=max&auto=format&n=3hg2JQs0m7qmDqay&q=85&s=a4a2b728a1037ddec24deec1138f40ff" alt="Exemple UWP : connexion" width="502" height="353" data-path="images/playfab/identity/player-identity/platform-specific-authentication/tutorials/uwp/uwp-example-sign-in.png" />

Suivez les instructions d'authentification proposées par Windows.

1. Une fois votre identité confirmée, un message de confirmation indique que le compte est **Signed in**.
2. Avec un **Session Ticket**.

<img src="https://mintcdn.com/microsoft-4404708b/3hg2JQs0m7qmDqay/images/playfab/identity/player-identity/platform-specific-authentication/tutorials/uwp/uwp-example-sign-in-confirmation.png?fit=max&auto=format&n=3hg2JQs0m7qmDqay&q=85&s=db561357a05f68c7b25a47529d678bf3" alt="Exemple UWP : confirmation de la connexion" width="711" height="358" data-path="images/playfab/identity/player-identity/platform-specific-authentication/tutorials/uwp/uwp-example-sign-in-confirmation.png" />

À ce stade, vous avez correctement intégré PlayFab à votre application UWP.


## Related topics

- [Configurer la connexion avec Battle.net pour PlayFab](/fr/services/playfab/identity/player-identity/platform-specific-authentication/battlenet-login.md)
- [Configuration de l'authentification PlayFab avec Facebook et Unity](/fr/services/playfab/identity/player-identity/platform-specific-authentication/facebook-unity.md)
- [Configuration de l'authentification PlayFab avec Twitch et HTML5](/fr/services/playfab/identity/player-identity/platform-specific-authentication/twitch-html5.md)
- [Configuration de l'authentification PlayFab avec Facebook et HTML5](/fr/services/playfab/identity/player-identity/platform-specific-authentication/facebook-html5.md)
- [Configuration de l'authentification PlayFab avec Kongregate et Unity](/fr/services/playfab/identity/player-identity/platform-specific-authentication/kongregate-unity.md)
