Azure Notification Hubs から安全なプッシュ通知を送信する
概要
Microsoft Azure でプッシュ通知がサポートされたことで、マルチプラットフォームに対応し、簡単に使用できる、スケールアウトされたプッシュ通知インフラストラクチャを利用できるようになりました。これにより、モバイル プラットフォーム向けアプリケーション (コンシューマー用途およびエンタープライズ用途) にプッシュ通知機能を実装する作業が大幅に簡略化されます。
規制やセキュリティの制約により、アプリケーションでは、標準のプッシュ通知インフラストラクチャからは転送できないものを通知に含める必要がある場合があります。 このチュートリアルでは、クライアントのデバイスとアプリケーションのバックエンドとの間の安全で認証された接続を通して機密情報を送信することによって、同じエクスペリエンスを実現する方法について説明します。
大まかには、フローは次のようになります。
- アプリケーションのバックエンド:
- バックエンド データベースに安全なペイロードを格納します。
- この通知の ID をデバイスに送信します (安全でない情報は送信しません)。
- 通知を受け取ったときのデバイスのアプリケーション:
- デバイスは、安全なペイロードを要求するバックエンドにアクセスします。
- アプリケーションはデバイスに通知としてペイロードを表示できます。
重要なのは、前のフロー (およびこのチュートリアル) では、デバイスは、ユーザーがログインした後、認証トークンをローカル ストレージに保存すると想定していることです。 デバイスはこのトークンを使用して通知の安全なペイロードを取得できるため、これによって完全にシームレスなエクスペリエンスが保証されます。 アプリケーションがデバイスに認証トークンを格納しない、またはそれらのトークンが期限切れの場合、デバイスのアプリケーションは、通知を受け取ったときにアプリケーションの起動を促す一般的な通知を表示する必要があります。 その後、アプリケーションはユーザーを認証し、通知ペイロードを表示します。
このチュートリアルでは、プッシュ通知を安全に送信する方法について説明します。 このチュートリアルは、ユーザーへの通知に関するチュートリアルに基づいて作成されているため、先にそのチュートリアルの手順を完了する必要があります。
注意
このチュートリアルは、ユニバーサル Windows プラットフォーム アプリへの通知の送信に関するチュートリアルでの説明に従って、通知ハブの作成および構成が行われていることを想定しています。 また、Windows Phone 8.1 には (Windows Phone ではなく) Windows の資格情報が必要で、Windows Phone 8.0 または Silverlight 8.1 ではバックグラウンド タスクが機能しないことに注意してください。 Windows ストア アプリケーションの場合は、アプリケーションでロック画面が有効 (Appmanifest でチェック ボックスをオンにする) な場合にだけバックグラウンド タスクから通知を受信できます。
Web API プロジェクト
Visual Studio で、 ユーザーへの通知 チュートリアルで作成した AppBackend プロジェクトを開きます。
Notifications.cs の Notifications クラス全体を次のコードで置き換えます。 必ず、プレースホルダーを通知ハブの (フル アクセスを持つ) 接続文字列とハブの名前に置き換えます。 これらの値は Azure ポータルから取得できます。 ここで、このモジュールは、送信される、セキュリティで保護された別の通知を表します。 完全な実装では、通知はデータベースに格納されますが、ここでは、操作を簡単にするために、メモリに格納します。
public class Notification { public int Id { get; set; } public string Payload { get; set; } public bool Read { get; set; } } public class Notifications { public static Notifications Instance = new Notifications(); private List<Notification> notifications = new List<Notification>(); public NotificationHubClient Hub { get; set; } private Notifications() { Hub = NotificationHubClient.CreateClientFromConnectionString("{conn string with full access}", "{hub name}"); } public Notification CreateNotification(string payload) { var notification = new Notification() { Id = notifications.Count, Payload = payload, Read = false }; notifications.Add(notification); return notification; } public Notification ReadNotification(int id) { return notifications.ElementAt(id); } }
NotificationsController.cs の NotificationsController クラス定義内のコードを次のコードで置き換えます。 このコンポーネントは、デバイスが安全に通知を取得する方法を実装します。また、(このチュートリアルでは) 自分のデバイスへの安全なプッシュをトリガーする方法も提供します。 通知ハブに通知を送信するときに、通知の ID のみを含む (実際のメッセージは含まない) 直接通知を送信することに注意してください。
public NotificationsController() { Notifications.Instance.CreateNotification("This is a secure notification!"); } // GET api/notifications/id public Notification Get(int id) { return Notifications.Instance.ReadNotification(id); } public async Task<HttpResponseMessage> Post() { var secureNotificationInTheBackend = Notifications.Instance.CreateNotification("Secure confirmation."); var usernameTag = "username:" + HttpContext.Current.User.Identity.Name; // windows var rawNotificationToBeSent = new Microsoft.Azure.NotificationHubs.WindowsNotification(secureNotificationInTheBackend.Id.ToString(), new Dictionary<string, string> { {"X-WNS-Type", "wns/raw"} }); await Notifications.Instance.Hub.SendNotificationAsync(rawNotificationToBeSent, usernameTag); // apns await Notifications.Instance.Hub.SendAppleNativeNotificationAsync("{\"aps\": {\"content-available\": 1}, \"secureId\": \"" + secureNotificationInTheBackend.Id.ToString() + "\"}", usernameTag); // gcm await Notifications.Instance.Hub.SendGcmNativeNotificationAsync("{\"data\": {\"secureId\": \"" + secureNotificationInTheBackend.Id.ToString() + "\"}}", usernameTag); return Request.CreateResponse(HttpStatusCode.OK); }
Post
メソッドは、トースト通知を送信しません。 通知 ID のみを含み、慎重な扱いを要するコンテンツは含まない直接通知を送信します。 また、通知ハブで資格情報を構成していないプラットフォームの送信操作は必ずコメント アウトしてください。そうしないと、エラーになります。
- 次に、このアプリを Azure の Web サイトにもう一度デプロイして、すべてのデバイスからアクセスできるようにします。 AppBackend プロジェクトを右クリックして [発行] を選択します。
- 発行先として Azure の Web サイトを選択します。 Azure アカウントでサインインし、既存または新規の Web サイトを選択します。 [接続] タブの [宛先 URL] プロパティをメモしておきます。後で、この URL を バックエンド エンドポイント として参照します。 [発行] をクリックします。
Windows Phone プロジェクトの変更
NotifyUserWindowsPhone プロジェクトで、次のコードを App.xaml.cs に追加して、プッシュ バックグラウンド タスクを登録します。
OnLaunched()
メソッドの最後に次のコード行を追加します。RegisterBackgroundTask();
引き続き App.xaml.cs で、
OnLaunched()
の直後に次のコードを追加します。private async void RegisterBackgroundTask() { if (!Windows.ApplicationModel.Background.BackgroundTaskRegistration.AllTasks.Any(i => i.Value.Name == "PushBackgroundTask")) { var result = await BackgroundExecutionManager.RequestAccessAsync(); var builder = new BackgroundTaskBuilder(); builder.Name = "PushBackgroundTask"; builder.TaskEntryPoint = typeof(PushBackgroundComponent.PushBackgroundTask).FullName; builder.SetTrigger(new Windows.ApplicationModel.Background.PushNotificationTrigger()); BackgroundTaskRegistration task = builder.Register(); } }
App.xaml.cs ファイルの先頭に次の
using
ステートメントを追加します。using Windows.Networking.PushNotifications; using Windows.ApplicationModel.Background;
Visual Studio の [ファイル] メニューで [すべて保存] をクリックします。
プッシュ バックグラウンド コンポーネントの作成
次の手順では、プッシュ バックグラウンド コンポーネントを作成します。
ソリューション エクスプローラーで、ソリューションの最上位ノード (この場合は、Solution SecurePush) を右クリックし、 [追加] 、 [新しいプロジェクト] の順にクリックします。
[ストア アプリ] を展開し、 [Windows Phone アプリ] 、 [Windows ランタイム コンポーネント (Windows Phone)] の順にクリックします。 プロジェクトの名前として「PushBackgroundComponent」と入力し、 [OK] をクリックしてプロジェクトを作成します。
ソリューション エクスプローラーで、PushBackgroundComponent (Windows Phone 8.1) プロジェクトを右クリックし、 [追加] 、 [クラス] の順にクリックします。 新しいクラスに
PushBackgroundTask.cs
という名前を付けます。 [追加] をクリックしてクラスを生成します。PushBackgroundComponent
名前空間定義の内容全体を次のコードで置き換えます。プレースホルダー{back-end endpoint}
をバックエンドのデプロイ時に取得したバックエンド エンドポイントで置き換えます。public sealed class Notification { public int Id { get; set; } public string Payload { get; set; } public bool Read { get; set; } } public sealed class PushBackgroundTask : IBackgroundTask { private string GET_URL = "{back-end endpoint}/api/notifications/"; async void IBackgroundTask.Run(IBackgroundTaskInstance taskInstance) { // Store the content received from the notification so it can be retrieved from the UI. RawNotification raw = (RawNotification)taskInstance.TriggerDetails; var notificationId = raw.Content; // retrieve content BackgroundTaskDeferral deferral = taskInstance.GetDeferral(); var httpClient = new HttpClient(); var settings = ApplicationData.Current.LocalSettings.Values; httpClient.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Basic", (string)settings["AuthenticationToken"]); var notificationString = await httpClient.GetStringAsync(GET_URL + notificationId); var notification = JsonConvert.DeserializeObject<Notification>(notificationString); ShowToast(notification); deferral.Complete(); } private void ShowToast(Notification notification) { ToastTemplateType toastTemplate = ToastTemplateType.ToastText01; XmlDocument toastXml = ToastNotificationManager.GetTemplateContent(toastTemplate); XmlNodeList toastTextElements = toastXml.GetElementsByTagName("text"); toastTextElements[0].AppendChild(toastXml.CreateTextNode(notification.Payload)); ToastNotification toast = new ToastNotification(toastXml); ToastNotificationManager.CreateToastNotifier().Show(toast); } }
ソリューション エクスプローラーで PushBackgroundComponent (Windows Phone 8.1) プロジェクトを右クリックし、 [NuGet パッケージの管理] をクリックします。
左側で、 [オンライン] をクリックします。
[検索] ボックスに、「Http Client」と入力します。
結果の一覧で、 [Microsoft HTTP Client Libraries] 、 [インストール] の順にクリックします。 インストールを完了します。
NuGet [検索] ボックスに戻り、「Json.net」と入力します。 Json.NET パッケージをインストールし、NuGet パッケージ マネージャーのウィンドウを閉じます。
PushBackgroundTask.cs
ファイルの先頭に、次のusing
ステートメントを追加します。using Windows.ApplicationModel.Background; using Windows.Networking.PushNotifications; using System.Net.Http; using Windows.Storage; using System.Net.Http.Headers; using Newtonsoft.Json; using Windows.UI.Notifications; using Windows.Data.Xml.Dom;
ソリューション エクスプローラーで、NotifyUserWindowsPhone (Windows Phone 8.1) プロジェクトの [参照] を右クリックし、 [参照の追加] をクリックします。参照マネージャー ダイアログで、PushBackgroundComponent のチェック ボックスをオンにして、 [OK] をクリックします。
ソリューション エクスプローラーで、NotifyUserWindowsPhone (Windows Phone 8.1) プロジェクトの [Package.appxmanifest] をダブルクリックします。 [通知] で、 [トースト対応] を [はい] に設定します。
引き続き Package.appxmanifest で、上部の [宣言] メニューをクリックします。 [使用可能な宣言] ボックスで、 [バックグラウンド タスク] 、 [追加] の順にクリックします。
Package.appxmanifest で、 [プロパティ] の [プッシュ通知] チェック ボックスをオンにします。
Package.appxmanifest で、 [アプリ設定] の [エントリ ポイント] フィールドに「PushBackgroundComponent.PushBackgroundTask」と入力します。
[ファイル] メニューの [すべて保存] をクリックします。
アプリケーションの実行
アプリケーションを実行するには、以下の手順に従います。
- Visual Studio で、 AppBackend Web API アプリケーションを実行します。 ASP.NET Web ページが表示されます。
- Visual Studio で、 NotifyUserWindowsPhone (Windows Phone 8.1) Windows Phone アプリケーションを実行します。 Windows Phone エミュレーターが自動的に起動し、アプリケーションを読み込みます。
- NotifyUserWindowsPhone アプリケーションの UI で、ユーザー名とパスワードを入力します。 文字列は任意ですが、値は同じである必要があります。
- NotifyUserWindowsPhone アプリケーションの UI で、 [ログインして登録] をクリックします。 次に、 [プッシュを送信する] をクリックします。