背水一戰 Windows 10 (84) - 用戶和賬號: 微軟賬號的登錄和注銷


[源碼下載]


背水一戰 Windows 10 (84) - 用戶和賬號: 微軟賬號的登錄和注銷



作者:webabcd


介紹
背水一戰 Windows 10 之 用戶和賬號

  • 微軟賬號的登錄和注銷



示例
演示如何將微軟賬號的登錄和注銷集成到 app 中
UserAndAccount/MicrosoftAccount.xaml

<Page
    x:Class="Windows10.UserAndAccount.MicrosoftAccount"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:local="using:Windows10.UserAndAccount"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    mc:Ignorable="d">

    <Grid Background="Transparent">
        <StackPanel Margin="10 0 10 10">

            <Button Name="button" Content="登錄/注銷" Margin="5" Click="button_Click" />

            <TextBlock Name="lblMsg" Margin="5" />

            <Ellipse Width="48" Height="48" HorizontalAlignment="Left" Margin="5">
                <Ellipse.Fill>
                    <ImageBrush x:Name="imagePicture" />
                </Ellipse.Fill>
            </Ellipse>

        </StackPanel>
    </Grid>
</Page>

UserAndAccount/MicrosoftAccount.xaml.cs

/*
 * 演示如何將微軟賬號的登錄和注銷集成到 app 中
 * 
 * AccountsSettingsPane - 賬號配置界面
 *     Show() - 彈出界面
 *     GetForCurrentView() - 獲取當前的 AccountsSettingsPane 實例
 *     AccountCommandsRequested - 彈出界面時觸發的事件(事件參數為:AccountsSettingsPaneCommandsRequestedEventArgs)
 *     
 * AccountsSettingsPaneCommandsRequestedEventArgs
 *     GetDeferral() - 獲取異步操作對象
 *     HeaderText - 彈出界面上需要顯示的標題文字
 *     Commands - 返回一個 SettingsCommand 列表,用於在界面上添加自定義按鈕
 * 
 *     
 *     
 * 流程簡述:
 * 
 * 登錄第一步,將指定的 web 賬號提供商添加到賬號登錄界面中
 * WebAccountProvider - web 賬號提供商(本例以微軟賬號為例)
 * WebAuthenticationCoreManager - 用於獲取指定的 WebAccountProvider
 * WebAccountProviderCommand - 用於將指定的 WebAccountProvider 添加到賬號登錄界面中
 * 
 * 登錄第二步,用戶在賬號登錄界面中登錄后
 * WebTokenRequest - 通過指定的 WebAccountProvider 獲取這個 web 請求對象
 * WebTokenRequestResult - 通過 WebAuthenticationCoreManager 和指定的 WebTokenRequest 獲取這個 web 請求結果
 * 
 * 注銷第一步,將指定的 web 賬號添加到賬號管理界面中
 * WebAccount - 通過 WebAuthenticationCoreManager 和指定的 WebAccountProvider 和指定的 userId 獲取這個 web 賬號對象
 * WebAccountCommand - 用於將指定的 WebAccount 添加到賬號管理界面中
 * 
 * 注銷第二步,用戶在賬號管理界面中選擇注銷后
 * WebAccount - 可以調用這個對象的注銷方法
 * 
 * 
 * 
 * 注:
 * 本例測試時會報 ProviderError 錯誤,因為“you must register your app under the Microsoft Store with a Microsoft developer account”
 * 給自己一個提醒,如果需要看效果的話,請參見自己寫的“打字通”app 中的 MicrosoftAccount.xaml
 */

using System;
using System.Net.Http;
using System.Threading.Tasks;
using Windows.Data.Json;
using Windows.Security.Authentication.Web.Core;
using Windows.Security.Credentials;
using Windows.UI.ApplicationSettings;
using Windows.UI.Popups;
using Windows.UI.Xaml;
using Windows.UI.Xaml.Controls;
using Windows.UI.Xaml.Media.Imaging;
using Windows.UI.Xaml.Navigation;

namespace Windows10.UserAndAccount
{
    public sealed partial class MicrosoftAccount : Page
    {
        const string MicrosoftAccountProviderId = "https://login.microsoft.com";
        const string ConsumerAuthority = "consumers";
        const string AccountScopeRequested = "wl.basic";
        const string AccountClientId = "none";

        private string _userId = null;

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

        protected override void OnNavigatedTo(NavigationEventArgs e)
        {
            base.OnNavigatedTo(e);

            // 彈出賬號配置界面時觸發的事件
            AccountsSettingsPane.GetForCurrentView().AccountCommandsRequested += OnAccountCommandsRequested;
        }

        protected override void OnNavigatedFrom(NavigationEventArgs e)
        {
            base.OnNavigatedFrom(e);

            AccountsSettingsPane.GetForCurrentView().AccountCommandsRequested -= OnAccountCommandsRequested;
        }

        private void button_Click(object sender, RoutedEventArgs e)
        {
            // 彈出賬號配置界面
            AccountsSettingsPane.Show();
        }

        private async void OnAccountCommandsRequested(AccountsSettingsPane sender, AccountsSettingsPaneCommandsRequestedEventArgs e)
        {
            AccountsSettingsPaneEventDeferral deferral = e.GetDeferral();

            if (_userId == null)
            {
                // 彈出賬號配置界面用於賬號登錄
                await ShowLoginUI(e);
                // 彈出界面上需要顯示的標題文字
                e.HeaderText = "請登錄";
            }
            else
            {
                // 彈出賬號配置界面用於賬號管理(本例用於演示注銷)
                await ShowLogoutUI(e);
                // 彈出界面上需要顯示的標題文字
                e.HeaderText = "請注銷";
            }

            // 在彈出界面上添加自定義按鈕
            e.Commands.Add(new SettingsCommand("help", "幫助", HelpInvoked));
            e.Commands.Add(new SettingsCommand("about", "關於", AboutInvoked));

            deferral.Complete();
        }

        private void HelpInvoked(IUICommand command)
        {
            lblMsg.Text = "用戶點擊了“幫助”按鈕";
        }

        private void AboutInvoked(IUICommand command)
        {
            lblMsg.Text = "用戶點擊了“關於”按鈕";
        }



        // 將指定的 web 賬號提供商添加到賬號登錄界面中
        private async Task ShowLoginUI(AccountsSettingsPaneCommandsRequestedEventArgs e)
        {
            WebAccountProvider provider = await WebAuthenticationCoreManager.FindAccountProviderAsync(MicrosoftAccountProviderId, ConsumerAuthority);
            WebAccountProviderCommand providerCommand = new WebAccountProviderCommand(provider, WebAccountProviderCommandInvoked);
            e.WebAccountProviderCommands.Add(providerCommand);
        }

        // 用戶在賬號登錄界面中登錄后
        private async void WebAccountProviderCommandInvoked(WebAccountProviderCommand command)
        {
            try
            {
                WebTokenRequest webTokenRequest = new WebTokenRequest(command.WebAccountProvider, AccountScopeRequested, AccountClientId);

                WebTokenRequestResult webTokenRequestResult = await WebAuthenticationCoreManager.RequestTokenAsync(webTokenRequest);

                if (webTokenRequestResult.ResponseStatus == WebTokenRequestStatus.Success)
                {
                    var response = webTokenRequestResult.ResponseData[0];
                    if (response != null)
                    {
                        // 拿到 userId,實際開發中一般會將此信息保存到本地
                        string userId = response.WebAccount.Id;
                        _userId = userId;
                        lblMsg.Text = "登錄成功,userId:" + userId;
                        lblMsg.Text += Environment.NewLine;

                        /*
                         * 微軟賬號的登錄過程到此就完成了
                         * 如果想通過 response.WebAccount.UserName 這種方式來獲取賬號的用戶名或其他信息的話,那是獲取不到的
                         * 需要帶着 response.Token 去請求 apis.live.net 來獲取相關信息,說明如下
                         */

                        // 登錄成功后,要通過拿到的 token 像下面這樣獲取用戶信息
                        var restApi = new Uri(@"https://apis.live.net/v5.0/me?access_token=" + response.Token);

                        using (var client = new HttpClient())
                        {
                            var infoResult = await client.GetAsync(restApi);
                            string content = await infoResult.Content.ReadAsStringAsync();
                            /* 獲取到的內容類似如下
                             {
                               "id": "abcd1234abcd1234", 
                               "name": "王磊", 
                               "first_name": "磊", 
                               "last_name": "王", 
                               "link": "https://profile.live.com/", 
                               "gender": null, 
                               "locale": "zh_CN", 
                               "updated_time": "2017-04-27T02:24:58+0000"
                             }
                             */
                            var jsonObject = JsonObject.Parse(content);
                            string name = jsonObject["name"].GetString() ?? "";
                            string locale = jsonObject["locale"].GetString() ?? "";
                            lblMsg.Text += $"name:{name}, locale:{locale}";

                            // 通過如下方式拿到用戶圖片
                            string profileId = jsonObject["id"].GetString() ?? "";
                            string pictureUrl = $"https://apis.live.net/v5.0/{profileId}/picture" ?? "";
                            imagePicture.ImageSource = new BitmapImage(new Uri(pictureUrl));
                        }
                    }
                }
                else
                {
                    lblMsg.Text = "登錄失敗:" + webTokenRequestResult.ResponseStatus.ToString();
                }
            }
            catch (Exception ex)
            {
                lblMsg.Text = ex.ToString();
            }
        }



        // 將指定的 web 賬號添加到賬號管理界面中
        private async Task ShowLogoutUI(AccountsSettingsPaneCommandsRequestedEventArgs e)
        {
            WebAccountProvider provider = await WebAuthenticationCoreManager.FindAccountProviderAsync(MicrosoftAccountProviderId, ConsumerAuthority);

            WebAccount account = await WebAuthenticationCoreManager.FindAccountAsync(provider, _userId);

            if (account != null)
            {
                // 最后一個參數用於指定當用戶選擇了賬號后,會出現哪些功能按鈕(我這里測試只有 SupportedWebAccountActions.Remove 是有效的)
                WebAccountCommand command = new WebAccountCommand(account, WebAccountCommandInvoked, SupportedWebAccountActions.Remove);
                e.WebAccountCommands.Add(command);
            }
            else
            {
                _userId = null;
            }
        }

        // 用戶在賬號管理界面中選擇了某項功能
        private async void WebAccountCommandInvoked(WebAccountCommand command, WebAccountInvokedArgs args)
        {
            // 用戶選擇的是注銷
            if (args.Action == WebAccountAction.Remove)
            {
                await command.WebAccount.SignOutAsync();

                _userId = null;

                lblMsg.Text = "注銷成功";
                imagePicture.ImageSource = null;
            }
        }
    }
}



OK
[源碼下載]


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM