使用三方賬號登錄應用應該對大家來說已經不是什么新鮮事兒了,但是今天為什么還要在這里跟大家聊這個話題呢,原因很簡單 Windows Azure Mobiles Service Authentication 身份驗證可以方便的幫你在應用中集成此功能。
此前我曾介紹過 Mobile Service的推送功能,其優勢是可以方便的向不同的平台設備推送消息通知(Windows、IOS、Android),並且不用擔心服務器過載問題。然而基於Windows Azure Mobile Service的身份驗證依然保留了這個優勢, 可以方便開發者的在不同平台的客戶端上配置三方登錄,經過新浪的同學們的努力今天我們終於與實現了與Windows Azure Mobile Service集成,成為第一個中國本土支持Mobile Service三方登錄身份驗證的提供商。
今天我在這里介紹一下如何使用Mobile Service的登錄驗證。首先既然我們使用新浪微博作為應用的三方登錄入口我們要先在新浪微博注冊我們的應用。
打開微博開放平台網站 http://open.weibo.com/, 登錄你的微博賬號,或注冊微博開放平台賬號。隨后點擊“微鏈接”- “創建應用” - “移動應用”
微鏈接
創建應用
移動應用
具體申請上線等步驟請詳見:移動客戶端接入接入指南
還有新手指南: 新手指南
注冊完成應用后我們會得到應用的 App Key 和 App Secret 這兩個字符串非常重要在配置 Mobile Service 的時候需要用到識別應用。
隨后我們登錄 Windows Azure 建一個新的 Mobile Service http://manage.windowsazure.com/
這里的Backed我們需要選擇.Net 我們可以選擇新建數據庫或加載到已有數據庫中去。
隨后我們可以看到新建好的 Mobile Service,並展開一個創建新的 Windows 或 Windows Phone App標簽,下載實例代碼 我這里以全新項目搭建流程為大家展示。當然如果你是非 Windows 平台開發者也不要擔心我們也同樣提供了其他平台的客戶端代碼模板。
請 IOS 開發者下載
請 Android 開發者下載
接下來我們引用在項目中引用 Windows Azure Mobile Service SDK 的方法有兩種。(大家可以根據項目需要選擇)
1. 新浪微博 Windows Azure Mobile Service SDK 鏈接:http://open.weibo.com/wiki/SDK 下載源碼在項目中引用(好處是可以調試)。
2. 在VS中通過 Nuget 直接下載 DLL 使用。(這個使用方法簡便,但是無法調試修改與Sina接口部分代碼)
首先介紹下載SDK源碼是的使用方法
下載實例代碼然后打開項目
將 microsoft.owin.security.sinaweibo 項目備份出來以便我們的項目使用,另外這個SLN本身就是一個Demo,感興趣的同學可以多多研究。
隨后打開我們之從Windows Azure網站上下載的實例代碼(主要是Mobile Service 網站項目)將 microsoft.owin.security.sinaweibo 引用進去。
添加項目成功
展開 Mobile Service 項目添加引用
引用SinaWeibo項目 隨后編譯,注:這時候有可能VS會自動下載要用DLL要多等一會
另一種方法是使用 NuGet 下載DLL。
在 Mobile Service 項目中右鍵點擊選擇 Manage NeGet Packages 選項
隨后搜索SDK的關鍵字 Sina 或者 SinaAzureMobileService 可以直接安裝DLL。
最后檢查 microsoft.owin.security.sinaweibo 已經引用到項目中來並編譯項目。
隨后在 Mobile Service 站點項目中選擇Web.Config 文件配置我們的 App Key 和 App Secret 如下:
<!-- SinaWeibo App ClientID/ClientSecret--> <add key="SinaWeiBoClientId" value="ClientID"/> <add key="SinaWeiBoClientSecret" value="ClientSecret"/>
接着我們要在服務器端添加兩個Class SinaWeiboLoginAuthenticationProvider 和 SinaWeiboLoginProvider 代碼如下
using System; using System.Collections.Generic; using System.Linq; using System.Web; using Owin; using Microsoft.Owin.Security.SinaWeibo; using Microsoft.Owin.Security.SinaWeibo.Provider; using System.Threading.Tasks; using System.Security.Claims; using Microsoft.WindowsAzure.Mobile.Service.Security; namespace WangBoAuthenticationSinaLoginService { public class SinaWeiboLoginAuthenticationProvider : SinaWeiboAccountAuthenticationProvider //SinaWeiBoAuthenticationProvider { public override Task Authenticated(SinaWeiboAccountAuthenticatedContext context) { context.Identity.AddClaim( new Claim(ServiceClaimTypes.ProviderAccessToken, context.AccessToken)); return base.Authenticated(context); } } }
SinaWeiboLoginProvider 代碼
using System; using System.Collections.Generic; using System.Linq; using System.Web; using Owin; using Microsoft.Owin.Security.SinaWeibo; using Microsoft.Owin.Security.SinaWeibo.Provider; using System.Threading.Tasks; using System.Security.Claims; using Microsoft.WindowsAzure.Mobile.Service.Security; namespace WangBoAuthenticationSinaLoginService { public class SinaWeiboLoginProvider : LoginProvider { internal const string ProviderName = "SinaWeibo"; public SinaWeiboLoginProvider(IServiceTokenHandler tokenHandler) : base(tokenHandler) { } public override void ConfigureMiddleware(IAppBuilder appBuilder, Microsoft.WindowsAzure.Mobile.Service.ServiceSettingsDictionary settings) { SinaWeiboAccountAuthenticationOptions options = new SinaWeiboAccountAuthenticationOptions { AppId = settings["SinaWeiBoClientId"], AppSecret = settings["SinaWeiBoClientSecret"], AuthenticationType = this.Name, Provider = new SinaWeiboAccountAuthenticationProvider() }; appBuilder.UseSinaWeiboAuthentication(options); } public override ProviderCredentials CreateCredentials(ClaimsIdentity claimsIdentity) { Claim name = claimsIdentity.FindFirst(ClaimTypes.NameIdentifier); Claim providerAccessToken = claimsIdentity .FindFirst(ServiceClaimTypes.ProviderAccessToken); SinaWeiboCredentials credentials = new SinaWeiboCredentials { UserId = this.TokenHandler.CreateUserId(this.Name, name != null ? name.Value : null), AccessToken = providerAccessToken != null ? providerAccessToken.Value : null }; return credentials; } public override string Name { get { return ProviderName; } } public override ProviderCredentials ParseCredentials(Newtonsoft.Json.Linq.JObject serialized) { return serialized.ToObject<SinaWeiboCredentials>(); } public class SinaWeiboCredentials : ProviderCredentials { public SinaWeiboCredentials() : base(SinaWeiboLoginProvider.ProviderName) { } public string AccessToken { get; set; } } } }
還有一個重要的步驟是在WebApiConfig的注冊方法中注冊新浪登陸的API
public static class WebApiConfig { public static void Register() { // Use this class to set configuration options for your mobile service ConfigOptions options = new ConfigOptions(); options.LoginProviders.Add(typeof(SinaWeiboLoginProvider)); // Use this class to set WebAPI configuration options HttpConfiguration config = ServiceConfig.Initialize(new ConfigBuilder(options)); // To display errors in the browser during development, uncomment the following // line. Comment it out again when you deploy your service for production use. // config.IncludeErrorDetailPolicy = IncludeErrorDetailPolicy.Always; Database.SetInitializer(new WangBoAuthenticationSinaLoginInitializer()); } }
下一步是部署我們的 Mobile Service 代碼,右鍵點擊項目選址發布
發布成功后瀏覽器會自動跳轉到 Destination URL 隨后點擊Try out 輸入密碼就可以跳轉到API的頁面說明我們的 Mobile Service 是健康的。
接着我們可以通過URL在IE中來測試訪問注冊是否成功 例如:
https://wangboauthenticationsinalogin.azure-mobile.net/login/sinaweibo【其中wangboauthenticationsinalogin.azure-mobile.net是我的服務名稱,這里需要替換成你自己的】
隨后我們要回到新浪開放平台設置我們的會掉授權頁面。這里需要注意的是回調授權頁需要采用 https:// 協議例如:
https://wangboauthenticationsinalogin.azure-mobile.net/signin-sinaWeibo 【其中wangboauthenticationsinalogin.azure-mobile.net是我的服務名稱,這里需要替換成你自己的】
接着我們開始設置客戶端代碼
首先打開Share Project中的 App.xaml.cs 注釋掉本地調試代碼使用遠程服務器地址
// This MobileServiceClient has been configured to communicate with your local // test project for debugging purposes. //public static MobileServiceClient MobileService = new MobileServiceClient( // "http://localhost:58974" //); // This MobileServiceClient has been configured to communicate with your Mobile Service's url // and application key. You're all set to start working with your Mobile Service! public static MobileServiceClient MobileService = new MobileServiceClient( "https://wangboauthenticationsinalogin.azure-mobile.net/", "密碼寫在這里" );
隨后打開 MainPage 添加一個驗證函數 AuthenticateAsync
private async Task AuthenticateAsync() { Microsoft.WindowsAzure.MobileServices.MobileServiceUser user = null; string message; try { user = await App.MobileService.LoginAsync("sinaweibo"); message = string.Format("You are now logged in - {0}", user.UserId + user.MobileServiceAuthenticationToken); } catch (InvalidOperationException ex) { string exm = ex.Message; message = "You must log in. Login Required"; } await Dispatcher.RunAsync(Windows.UI.Core.CoreDispatcherPriority.Normal, () => { var dialog = new MessageDialog(message); dialog.Commands.Add(new UICommand("OK")); dialog.ShowAsync(); }); }
然后我們需要在客戶端UI上添加一個登陸按鈕,打開 Windows8.1 項目找到 MainPage.xaml 添加注冊按鈕(就在刷新按鈕下面直接添加登陸了)
<Button Margin="72,0,0,0" Name="ButtonRefresh" Click="ButtonRefresh_Click">Refresh</Button> <Button Margin="72,0,0,0" x:Name="ButtonLogin" Click="ButtonLogin_Click" Content="Login"/>
在 share project 中的 MainPage.xaml.cs 代碼文件中添加事件處理函數
private async void ButtonLogin_Click(object sender, Windows.UI.Xaml.RoutedEventArgs e) { await AuthenticateAsync(); }
最后由於在 WindowsPhone 上進行驗證時應用會自動切換到后台所以我們需要處理一下OnActivated事件
protected override void OnActivated(IActivatedEventArgs args) { base.OnActivated(args); #if WINDOWS_PHONE_APP if (args.Kind == ActivationKind.WebAuthenticationBrokerContinuation) { App.MobileService.LoginComplete(args as WebAuthenticationBrokerContinuationEventArgs); } #endif }
完成后直接F5運行調試程序,下面我展示一下運行效果。
Windows 8.1 版認證過程
登錄成功拿到Token
WindowsPhone 8.1版認證過程
登錄成功拿到Token
希望上的總結可以幫助到大家, 同時歡迎大家在這里和我溝通交流或者在新浪微博上 @王博_Nick