Azure Notification Hubs Secure Push
نظرة عامة
يتيح لك دعم الإشعارات المباشرة في Microsoft Azure الوصول إلى بنية تحتية دفع سهلة الاستخدام ومتعددة الأنظمة الأساسية وقابلة للتوسعة، مما يبسط إلى حد كبير تنفيذ الإعلامات المباشرة لكل من تطبيقات المستهلكين والمؤسسات للمنصات المحمولة.
نظرا للقيود التنظيمية أو الأمنية، قد يرغب التطبيق أحيانا في تضمين شيء ما في الإشعار لا يمكن إرساله من خلال البنية التحتية القياسية للإشعارات الدفعية. يصف هذا البرنامج التعليمي كيفية تحقيق نفس التجربة عن طريق إرسال معلومات حساسة من خلال اتصال آمن ومصادق عليه بين الجهاز العميل والواجهة الخلفية للتطبيق.
على مستوى عال ، يكون التدفق كما يلي:
- الواجهة الخلفية للتطبيق:
- يخزن حمولة آمنة في قاعدة البيانات الخلفية.
- يرسل معرف هذا الإشعار إلى الجهاز (لا يتم إرسال أي معلومات آمنة).
- التطبيق على الجهاز ، عند تلقي الإشعار:
- يتصل الجهاز بالواجهة الخلفية لطلب الحمولة الآمنة.
- يمكن للتطبيق إظهار الحمولة كإشعار على الجهاز.
من المهم ملاحظة أنه في التدفق السابق (وفي هذا البرنامج التعليمي) ، نفترض أن الجهاز يخزن رمزا مميزا للمصادقة في التخزين المحلي ، بعد تسجيل دخول المستخدم. وهذا يضمن تجربة سلسة ، حيث يمكن للجهاز استرداد الحمولة الآمنة للإشعار باستخدام هذا الرمز المميز. إذا كان تطبيقك لا يخزن رموز المصادقة على الجهاز، أو إذا كان من الممكن انتهاء صلاحية هذه الرموز المميزة، فيجب أن يعرض تطبيق الجهاز، عند تلقي الإشعار، إشعارا عاما يطالب المستخدم بتشغيل التطبيق. ثم يقوم التطبيق بمصادقة المستخدم ويعرض حمولة الإشعار.
يوضح هذا البرنامج التعليمي Secure Push كيفية إرسال إشعار دفع بشكل آمن. يعتمد البرنامج التعليمي على البرنامج التعليمي لإعلام المستخدمين ، لذلك يجب عليك إكمال الخطوات الواردة في هذا البرنامج التعليمي أولا.
ملاحظة
يفترض هذا البرنامج التعليمي أنك قمت بإنشاء مركز الإشعارات وتكوينه كما هو موضح في إرسال إشعارات فورية إلى تطبيقات iOS باستخدام مراكز إعلام Azure.
WebAPI Project
في Visual Studio، افتح مشروع AppBackend الذي قمت بإنشائه في البرنامج التعليمي إعلام المستخدمين.
في الإشعارات.cs، استبدل فئة الإعلامات بالكامل بالتعليمة البرمجية التالية. تأكد من استبدال العناصر النائبة بسلسلة الاتصال (مع الوصول الكامل) لمركز الإعلام واسم الموزع. يمكنك الحصول على هذه القيم من مدخل 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 بالتعليمة البرمجية التالية. ينفذ هذا المكون طريقة للجهاز لاسترداد الإشعار بأمان ، ويوفر أيضا طريقة (لأغراض هذا البرنامج التعليمي) لتشغيل دفعة آمنة إلى أجهزتك. لاحظ أنه عند إرسال الإشعار إلى مركز الإشعارات، فإننا نرسل فقط إشعارا أوليا بمعرف الإشعار (وليس هناك رسالة فعلية):
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 الآن لا ترسل إعلاما منبثقا. يرسل إشعارا أوليا يحتوي فقط على معرف الإشعار ، وليس أي محتوى حساس. تأكد أيضا من التعليق على عملية الإرسال للأنظمة الأساسية التي ليس لديك بيانات اعتماد تم تكوينها على مركز الإشعارات الخاص بك ، لأنها ستؤدي إلى أخطاء.
- الآن سنقوم بإعادة نشر هذا التطبيق على موقع Azure على الويب من أجل جعله متاحا من جميع الأجهزة. انقر بزر الماوس الأيمن فوق مشروع AppBackendوحدد نشر.
- حدد موقع Azure على الويب كهدف للنشر. سجل الدخول باستخدام حساب Azure الخاص بك وحدد موقع ويب حالي أو جديدا، وقم بتدوين خاصية عنوان URL المقصود في علامة التبويب اتصال . سنشير إلى عنوان URL هذا كنقطة نهاية خلفية لاحقا في هذا البرنامج التعليمي. انقر على نشر.
تعديل مشروع iOS
الآن بعد أن قمت بتعديل الواجهة الخلفية لتطبيقك لإرسال معرف الإشعار فقط ، يجب عليك تغيير تطبيق iOS الخاص بك للتعامل مع هذا الإشعار والاتصال مرة أخرى بالواجهة الخلفية لاسترداد الرسالة الآمنة التي سيتم عرضها.
لتحقيق هذا الهدف ، يتعين علينا كتابة المنطق لاسترداد المحتوى الآمن من الواجهة الخلفية للتطبيق.
في
AppDelegate.m، تأكد من أن التطبيق يسجل للإشعارات الصامتة حتى يعالج معرف الإشعار المرسل من الواجهة الخلفية. أضف الخيار فيUIRemoteNotificationTypeNewsstandContentAvailabilitydidFinishLaunchingWithOptions:[[UIApplication sharedApplication] registerForRemoteNotificationTypes: UIRemoteNotificationTypeAlert | UIRemoteNotificationTypeBadge | UIRemoteNotificationTypeSound | UIRemoteNotificationTypeNewsstandContentAvailability];في قسم إضافة
AppDelegate.mتنفيذ في الجزء العلوي مع الإعلان التالي:@interface AppDelegate () - (void) retrieveSecurePayloadWithId:(int)payloadId completion: (void(^)(NSString*, NSError*)) completion; @endثم أضف في قسم التنفيذ التعليمة البرمجية التالية ، واستبدل العنصر النائب
{back-end endpoint}بنقطة النهاية للنهاية الخلفية التي تم الحصول عليها مسبقا:NSString *const GetNotificationEndpoint = @"{back-end endpoint}/api/notifications"; - (void) retrieveSecurePayloadWithId:(int)payloadId completion: (void(^)(NSString*, NSError*)) completion; { // check if authenticated ANHViewController* rvc = (ANHViewController*) self.window.rootViewController; NSString* authenticationHeader = rvc.registerClient.authenticationHeader; if (!authenticationHeader) return; NSURLSession* session = [NSURLSession sessionWithConfiguration:[NSURLSessionConfiguration defaultSessionConfiguration] delegate:nil delegateQueue:nil]; NSURL* requestURL = [NSURL URLWithString:[NSString stringWithFormat:@"%@/%d", GetNotificationEndpoint, payloadId]]; NSMutableURLRequest* request = [NSMutableURLRequest requestWithURL:requestURL]; [request setHTTPMethod:@"GET"]; NSString* authorizationHeaderValue = [NSString stringWithFormat:@"Basic %@", authenticationHeader]; [request setValue:authorizationHeaderValue forHTTPHeaderField:@"Authorization"]; NSURLSessionDataTask* dataTask = [session dataTaskWithRequest:request completionHandler:^(NSData *data, NSURLResponse *response, NSError *error) { NSHTTPURLResponse* httpResponse = (NSHTTPURLResponse*) response; if (!error && httpResponse.statusCode == 200) { NSLog(@"Received secure payload: %@", [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding]); NSMutableDictionary *json = [NSJSONSerialization JSONObjectWithData:data options: NSJSONReadingMutableContainers error: &error]; completion([json objectForKey:@"Payload"], nil); } else { NSLog(@"Error status: %ld, request: %@", (long)httpResponse.statusCode, error); if (error) completion(nil, error); else { completion(nil, [NSError errorWithDomain:@"APICall" code:httpResponse.statusCode userInfo:nil]); } } }]; [dataTask resume]; }تستدعي هذه الطريقة الواجهة الخلفية لتطبيقك لاسترداد محتوى الإشعارات باستخدام بيانات الاعتماد المخزنة في التفضيلات المشتركة.
الآن تعامل مع الإشعار الوارد واستخدم الطريقة المذكورة أعلاه لاسترداد المحتوى المراد عرضه. أولا ، قم بتمكين تطبيق iOS الخاص بك من التشغيل في الخلفية عند تلقي إشعار دفع. في XCode، حدد مشروع تطبيقك على اللوحة اليمنى، ثم انقر على هدف التطبيق الرئيسي في قسم الأهداف من الجزء المركزي.
ثم انقر فوق علامة التبويب الإمكانات في أعلى الجزء المركزي ، وحدد المربع الإعلامات عن بعد .

في
AppDelegate.mإضافة الطريقة التالية للتعامل مع الإعلامات دفع:-(void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo fetchCompletionHandler:(void (^)(UIBackgroundFetchResult))completionHandler { NSLog(@"%@", userInfo); [self retrieveSecurePayloadWithId:[[userInfo objectForKey:@"secureId"] intValue] completion:^(NSString * payload, NSError *error) { if (!error) { // show local notification UILocalNotification* localNotification = [[UILocalNotification alloc] init]; localNotification.fireDate = [NSDate dateWithTimeIntervalSinceNow:0]; localNotification.alertBody = payload; localNotification.timeZone = [NSTimeZone defaultTimeZone]; [[UIApplication sharedApplication] scheduleLocalNotification:localNotification]; completionHandler(UIBackgroundFetchResultNewData); } else { completionHandler(UIBackgroundFetchResultFailed); } }]; }لاحظ أنه من الأفضل التعامل مع حالات فقدان خاصية رأس المصادقة أو الرفض بواسطة الواجهة الخلفية. يعتمد التعامل المحدد لهذه الحالات في الغالب على تجربة المستخدم المستهدفة. أحد الخيارات هو عرض إشعار مع مطالبة عامة للمستخدم بالمصادقة لاسترداد الإشعار الفعلي.
تشغيل التطبيق
لتشغيل التطبيق، قم بما يلي:
- في XCode ، قم بتشغيل التطبيق على جهاز iOS فعلي (لن تعمل إشعارات الدفع في جهاز المحاكاة).
- في واجهة مستخدم تطبيق iOS، أدخل اسم مستخدم وكلمة مرور. يمكن أن تكون هذه أي سلسلة ، ولكن يجب أن تكون نفس القيمة.
- في واجهة مستخدم تطبيق iOS، انقر على تسجيل الدخول. ثم انقر على إرسال دفعة. من المفترض أن ترى الإشعار الآمن معروضا في مركز الإشعارات.