قسمت هفتم چگونه به push service متصل شویم؟
در قسمت قبل از سری مقاله های «آموزش ارسال notification در یک سایت» به طور مفصل روال ارسال push notification برای کاربر را توضیح دادیم. گفتیم که برای این کار از یک سرویس سوم به نام push service استفاده می شود. بدین ترتیب که مرورگر کاربر ابتدا به push service مربوط به آن درخواست اشتراک می دهد، push service در پاسخ یک pushSubscription object
بر می گرداند و این pushSubscription object
به عنوان هویت مرورگر کاربر شناخته می شود. و از این پس اگر نیاز بود به مرورگر کاربر push notification ارسال شود، این شناسه به همراه متن و محتوای push notification برای push service ارسال می شود و push service آن را برای مرورگر ارسال می کند. همچنین گفتیم که فرایند ارسال درخواست به push service برای ارسال push notification معمولاً از طریق کتابخانه های مخصوص انجام می گیرد و نیازی نیست که خودمان از پایه کد بنویسیم. علیرغم این که شرکت های سازنده ی مرورگر های مختلف هر یک به شیوه ای push service خود را پیاده کرده اند، از آنجا که این درخواست (web push protocol request ) استاندارد خاص خودش را دارد، صرفاً با رعایت استاندارد های مربوطه می توان در همه ی بستر ها از یک کد واحد استفاده کرد. به این ترتیب نگرانی بابت تفاوت نحوه پیاده سازی push service های مختلف با هم برطرف خواهد شد.
برای مثال این استاندارد به ما می گوید که درخواست باید header های خاصی داشته باشد و داده ها باید به صورت جریانی از بایت ها ارسال شوند.
پیش تر گفتیم که pushSubscription object
پاسخیست که push service به ازای درخواست اشتراک کاربر به ما می دهد. در زیر یک نمونه ی pushSubscription object
را مشاهده می کنید:
{
"endpoint": "https://fcm.googleapis.com/fcm/send/c1KrmpTuRm…",
"expirationTime": null,
"keys": {
"p256dh": "BGyyVt9FFV…",
"auth": "R9sidzkcdf…"
}
}
- در قالب بالا دامنه ی endpoint همان آدرس push service است. (در مثال بالا fcm.googleapis.com)
مسیر نهایی endpoint نیز مشخص کننده ی شناسه ی کاربر است که در بالا ذکر کردیم. یعنی کاربر منحصر به فردی که push notification باید برای او ارسال شود. expirationTime
نیز همان طور که از نامش پیداست، زمان انقضای این اشتراک را مشخص خواهد کرد.- مقادیر مربوط به keys کلید هایی هستند که برای رمزنگاری مورد استفاده قرار می گیرند.
چرا باید درخواست ارسال push notification رمزنگاری شده باشد؟
از آنجا که شرکت های سازنده ی مرورگر های مختلف از push service های مختلفی استفاده می کنند، کد push service به صورت بالقوه ممکن است ناامن باشد یا بخواهد به محتوای داده های ارسالی دسترسی داشته باشد، از این رو داده ای که برای push service ارسال می شود، باید رمزنگاری شده باشد. این رمزنگاری از طریق کلیدهایی که در pushSubscription object
وجود دارد انجام می شود.
امضای web push protocol request چه کمکی به ما می کند؟
اگر درخواست web push protocol
امضای خاصی داشته باشد، هیچ کس به غیر از خودمان نمی تواند برای کاربرانمان پوش نوتیفیکیشن ارسال کند. (در مقاله ی قبل در مورد web push protocol توضیحات مفصلی ارائه کرده ایم.)
برای امضای درخواست و در نتیجه احراز هویت کاربران برای ارسال push notification دو کلید مورد نیاز است. یک private key و یک public key که برای برنامه ی ما منحصر به فرد هستند. می توانیم این کلید را با استفاده از کتابخانه های مخصوص (مانند کتابخانه ی web-push تولید کنیم). کلید خصوصی باید در اختیار سرور برنامه باشد تا بتواند نحوه ی احراز هویت push notification را به push service اعلام کند. کلید عمومی نیز در اختیار client است و هر گاه مرورگر خواست خود را مشترک push notification های push service کند، درخواستش را با ارسال این کلید عمومی به push service ارسال می کند. به این ترتیب push service نیز این کلید عمومی را دریافت و ذخیره خواهد کرد. داشتن کلید عمومی به رمزگشایی پیامی که از سمت سرور برای push service می فرستیم کمک خواهد کرد. به طور کلی روند این احراز هویت به صورت زیر است:
- نخست یک کلید عمومی(public key) و یک کلید خصوصی(private key) تولید می کنیم. در برخی مستند ها نیز این کلید ها را با نام
VAPID keys
می شناسند. می توانیم این کلید ها را با استفاده از کتابخانه های مخصوص تولید کنیم که نمونه ی آن را در قسمت های بعدی مقاله خواهید دید. - مقدار کلید عمومی تولید شده در اختیار client نیز قرار می گیرد. هنگامی که یک client (مثلاً مرورگر کاربر) را مشترک push notification می کنیم (یعنی درخواست اشتراک را به push service ارسال می کنیم)، public key را به آن می دهیم تا با استفاده از آن endpoint مربوط به ارسال نوتیفیکیشن را برای ما ایجاد کند. به عبارت دیگر مرورگر کاربر وقتی می خواهد درخواست اشتراک بدهد، کلید عمومی را نیز می فرستد. به این کلید عمومی
applicationServerKey
نیز گفته می شود. - از طرفی در سمت سرور، وقتی می خواهیم یک درخواست
web push protocol
ارسال کنیم، داده های JSON ای که می خواهیم به عنوان محتوای push notification ارسال کنیم را با استفاده از کلید خصوصی امضا می کنیم و برای آن می فرستیم. - وقتی push service درخواست
web push protocol
ما را دریافت می کند، از کلید عمومی ذخیره شده ی خود برای احراز هویت داده ی رمزنگاری شده استفاده می کند. اگر امضای آن معتبر بود (یعنی احراز هویت با موفقیت انجام شد) push service اطمینان حاصل می کند که درخواست از سرور با کلید خصوصی صحیح (سرور برنامه ی خودمان) دریافت شده.
نمودار زیر خلاصه ای از موارد بالا را به تصویر کشیده است:
البته خوب است بدانیم که امضا داشتن درخواست در برخی مرورگر ها الزامی و در برخی دیگر الزامی نیست. برای مثال امضای درخواست در chrome الزامیست اما در firefox دلخواه است.
سفارشی سازی نحوه ی تحویل push notification
هنگام ارسال درخواست web push protocol
می توان با تعیین پارامتر هایی، مشخص کنیم که رفتار push service برای تحویل push notification چگونه باشد. مواردی از قبیل:
- تعیین زمان زندگی (
Time-To-Live
یاTTL
) پیام. - ضروری بودن یا نبودن پیام. برای مثال در برخی مواقع push service برای ذخیره ی باتری سیستم کاربر، تنها پیام های ضروری را برای او ارسال می کند که با این معیار می توانیم ضروری بودن یا نبودن پیام را مشخص کنیم.
- موضوع (topic) پیام. وقتی یک پیام در صف ارسال است ولی هنوز ارسال نشده و به دست کاربر نرسیده، در حالت pending قرار دارد. وقتی پیامی در حالت pending قرار دارد و در همان حین یک پیام جدید با همان موضوع در صف ارسال قرار می گیرد، پیام قبلی جایگزین پیام جدید خواهد شد.
دریافت و نمایش نوتیفیکیشن ارسال شده
هنگامی که با استفاده از web push protocol request
درخواستی به push service می دهیم تا پیامی برای ما ارسال کند، این پیام توسط push service در صف قرار می گیرد تا یکی از دو اتفاق زیر برای آن رخ دهد:
- client آنلاین شود و push service پیام را به دست آن برساند.
- زمان push notification منقضی شود.
وقتی مرورگر کاربری push notification را دریافت می کند، محتوای آن را رمزگشایی می کند و رخ دادن اتفاق push را به service worker اطلاع می دهد. در کد service worker و در handler مربوط به اتفاق push نیز push notification نمایش داده می شود.تا کنون مفاهیم پایه ای مربوط به ارسال و دریافت push notification را بهتر درک کردیم و از پشت پرده ی تکنولوژی های مورد استفاده خبر دار شدیم. حال زمان انتظار به پایان رسیده و در ادامه با ایجاد پروژه یک پروژه ی کوچک، هم در قسمت backend و هم در قسمت frontend یک سیستم ارسال و دریافت push notification ساده خواهیم نوشت.
در قسمت بعد، این آموزش را با هم ادامه خواهیم داد.