背水一戰 Windows 10 之 用戶和賬號: 數據賬號的添加和管, OAuth 2.0 驗證 ...
背水一戰 Windows 10 (83) - 用戶和賬號: 數據賬號的添加和管理, OAuth 2.0 驗證
作者:webabcd
介紹
背水一戰 Windows 10 之 用戶和賬號
- 數據賬號的添加和管
- OAuth 2.0 驗證
示例
1、演示數據賬號的添加和管理
UserAndAccount/DataAccount.xaml
<Page x:Class="Windows10.UserAndAccount.DataAccount" 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"> <TextBlock Name="lblMsg" Margin="5" /> <Button Name="buttonAdd" Content="新增一個數據賬號" Margin="5" Click="buttonAdd_Click" /> </StackPanel> </Grid> </Page>
UserAndAccount/DataAccount.xaml.cs
/* * 演示數據賬號的添加和管理 * * UserDataAccountManager - 數據賬號管理器 * ShowAddAccountAsync() - 彈出賬號添加界面 * ShowAccountSettingsAsync() - 彈出賬號管理界面 * RequestStoreAsync() - 返回當前用戶的數據賬號存儲區域 * GetForUser() - 返回指定用戶的數據賬號存儲區域(通過返回的 UserDataAccountManagerForUser 對象的 RequestStoreAsync() 方法) * * UserDataAccountStore - 數據賬號存儲區域 * FindAccountsAsync() - 返回所有的數據賬號 * GetAccountAsync() - 返回指定的數據賬號 * * UserDataAccount - 數據賬號 * UserDisplayName - 用戶名 * Id - 數據賬號在本地設備上的唯一標識 * SaveAsync() - 保存 * DeleteAsync() - 刪除 * ... 還有很多其他屬性和方法 * * * 註:根據使用的功能需要在 Package.appxmanifest 做相關配置 * 1、用到 Windows.System.User 的話需要配置 <Capability Name="userAccountInformation" /> * 2、還可能需要 <Capability Name="appointments" />, <Capability Name="contacts" /> */ using System; using System.Linq; using System.Collections.Generic; using Windows.ApplicationModel.UserDataAccounts; using Windows.UI.Xaml; using Windows.UI.Xaml.Controls; using Windows.UI.Xaml.Navigation; namespace Windows10.UserAndAccount { public sealed partial class DataAccount : Page { public DataAccount() { this.InitializeComponent(); } protected async override void OnNavigatedTo(NavigationEventArgs e) { base.OnNavigatedTo(e); // 獲取當前用戶下的全部數據賬號 UserDataAccountStore store = await UserDataAccountManager.RequestStoreAsync(UserDataAccountStoreAccessType.AllAccountsReadOnly); IReadOnlyList<UserDataAccount> accounts = await store.FindAccountsAsync(); lblMsg.Text += string.Join(",", accounts.Select(p => p.UserDisplayName)); lblMsg.Text += Environment.NewLine; } private async void buttonAdd_Click(object sender, RoutedEventArgs e) { // 彈出賬號添加界面,如果添加成功會返回新建的數據賬號的在本地設備上的唯一標識 string userDataAccountId = await UserDataAccountManager.ShowAddAccountAsync(UserDataAccountContentKinds.Email | UserDataAccountContentKinds.Appointment | UserDataAccountContentKinds.Contact); if (string.IsNullOrEmpty(userDataAccountId)) { lblMsg.Text += "用戶取消了或添加賬號失敗"; lblMsg.Text += Environment.NewLine; } else { UserDataAccountStore store = await UserDataAccountManager.RequestStoreAsync(UserDataAccountStoreAccessType.AllAccountsReadOnly); if (store != null) { // 通過數據賬號在本地設備上的唯一標識來獲取 UserDataAccount 對象 UserDataAccount account = await store.GetAccountAsync(userDataAccountId); lblMsg.Text += "新增的數據賬號:" + account.UserDisplayName; } } } } }
2、演示如何開發一個基於 OAuth 2.0 驗證的客戶端
UserAndAccount/OAuth20.xaml
<Page x:Class="Windows10.UserAndAccount.OAuth20" 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="buttonWeibo" Content="登錄新浪微博,並返回登錄用戶好友最新發佈的微博" Margin="5" Click="buttonWeibo_Click" /> <TextBlock Name="lblMsg" TextWrapping="Wrap" Margin="5" /> </StackPanel> </Grid> </Page>
UserAndAccount/OAuth20.xaml.cs
/* * 演示如何開發一個基於 OAuth 2.0 驗證的客戶端 * 關於 OAuth 2.0 協議請參見:http://tools.ietf.org/html/draft-ietf-oauth-v2-20 * * WebAuthenticationBroker - 用於 OAuth 2.0 驗證的第一步,可以將第三方 UI 無縫整合進 app * AuthenticateAsync(WebAuthenticationOptions options, Uri requestUri, Uri callbackUri) - 請求 authorization code,返回一個 WebAuthenticationResult 類型的數據 * * WebAuthenticationResult - 請求 authorization code(OAuth 2.0 驗證的第一步)的結果 * ResponseData - 響應的數據 * ResponseStatus - 響應的狀態 * * * 註:本例以微博開放平臺為例 */ using System; using System.Net.Http; using System.Text.RegularExpressions; using Windows.Data.Json; using Windows.Security.Authentication.Web; using Windows.UI.Xaml; using Windows.UI.Xaml.Controls; namespace Windows10.UserAndAccount { public sealed partial class OAuth20 : Page { public OAuth20() { this.InitializeComponent(); } private async void buttonWeibo_Click(object sender, RoutedEventArgs e) { try { var appKey = "39261162"; var appSecret = "652ec0b02f814d514fc288f3eab2efda"; var callbackUrl = "http://webabcd.cnblogs.com"; // 在新浪微博開放平臺設置的回調頁 var requestAuthorizationCode_url = string.Format("https://api.weibo.com/oauth2/authorize?client_id={0}&response_type=code&redirect_uri={1}", appKey, callbackUrl); // 第一步:request authorization code WebAuthenticationResult WebAuthenticationResult = await WebAuthenticationBroker.AuthenticateAsync( WebAuthenticationOptions.None, new Uri(requestAuthorizationCode_url), new Uri(callbackUrl)); // 第一步的結果 lblMsg.Text = WebAuthenticationResult.ResponseStatus.ToString() + Environment.NewLine; if (WebAuthenticationResult.ResponseStatus == WebAuthenticationStatus.Success) { // 從第一步返回的數據中獲取 authorization code var authorizationCode = QueryString(WebAuthenticationResult.ResponseData, "code"); lblMsg.Text += "authorizationCode: " + authorizationCode + Environment.NewLine; var requestAccessToken_url = string.Format("https://api.weibo.com/oauth2/access_token?client_id={0}&client_secret={1}&grant_type=authorization_code&redirect_uri={2}&code={3}", appKey, appSecret, callbackUrl, authorizationCode); // 第二步:request access token HttpClient client = new HttpClient(); var response = await client.PostAsync(new Uri(requestAccessToken_url), null); // 第二步的結果:獲取其中的 access token var jsonString = await response.Content.ReadAsStringAsync(); JsonObject jsonObject = JsonObject.Parse(jsonString); var accessToken = jsonObject["access_token"].GetString(); lblMsg.Text += "accessToken: " + accessToken + Environment.NewLine; var requestProtectedResource_url = string.Format("https://api.weibo.com/2/statuses/friends_timeline.json?access_token={0}", accessToken); // 第三步:request protected resource,獲取需要的數據(本例為獲取登錄用戶好友最新發佈的微博) var result = await client.GetStringAsync(new Uri(requestProtectedResource_url)); // 由於本 app 沒有提交微博開放平臺審核,所以如果使用的賬號沒有添加到微博開放平臺的測試賬號中的話,是會出現異常的 lblMsg.Text += "result: " + result; } } catch (Exception ex) { lblMsg.Text += Environment.NewLine; lblMsg.Text += ex.ToString(); } } /// <summary> /// 模擬 QueryString 的實現 /// </summary> /// <param name="queryString">query 字元串</param> /// <param name="key">key</param> private string QueryString(string queryString, string key) { return Regex.Match(queryString, string.Format(@"(?<=(\&|\?|^)({0})\=).*?(?=\&|$)", key), RegexOptions.IgnoreCase).Value; } } } /* * OAuth 2.0 的 Protocol Flow +--------+ +---------------+ | |--(A)- Authorization Request ->| Resource | | | | Owner | | |<-(B)-- Authorization Grant ---| | | | +---------------+ | | | | +---------------+ | |--(C)-- Authorization Grant -->| Authorization | | Client | | Server | | |<-(D)----- Access Token -------| | | | +---------------+ | | | | +---------------+ | |--(E)----- Access Token ------>| Resource | | | | Server | | |<-(F)--- Protected Resource ---| | +--------+ +---------------+ */
OK
[源碼下載]