الرمز المميز وتحديث الرمز المميز وإنشاء برنامج التفاف غير متزامن لطلب REST

صورة في هذا البرنامج التعليمي ، سنراجع بإيجاز كيفية تنفيذ طلبات REST إلى واجهة برمجة التطبيقات التي تتطلب تخويل المستخدم ، وإنشاء "ملف" غير متزامن للطلب ، والذي سوف يتحقق من الترخيص وتحديثه في الوقت المناسب.

معلومات تسجيل الدخول


بعد تقديم طلب REST إلى api ، حيث أرسلنا اسم المستخدم وكلمة المرور ، بالمقابل نحصل على json بالتنسيق التالي (القيم عشوائية وعادة ما تكون الأسطر أطول):

{ "access_token": "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpc3MiOiJPbmxpbmUgSld", "refresh_token": "1eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpc3MiOiJPbmxpbmUgS", "expires_in": 124234149563 } 

قد يكون هناك المزيد من الحقول في الاستجابة ، على سبيل المثال ، "token_type" ، و "expires_on" ، وما إلى ذلك ، ولكن بالنسبة لهذا التطبيق ، نحتاج فقط إلى الحقول الثلاثة أعلاه.
دعونا نلقي نظرة فاحصة عليها:

  • access_token - الرمز المميز الذي سنحتاج إلى إرساله في رأس كل طلب لتلقي البيانات استجابة
  • refresh_token - الرمز المميز الذي سنحتاج إلى إرساله لاستلام رمز مميز جديد عند انتهاء صلاحية الرمز القديم
  • expires_in - العمر المميز في ثوان

تلقي الرمز المميز


الآن قم بإنشاء وظيفة ستحصل على json الموضحة أعلاه واحفظها.

سنقوم بتخزين البيانات للحصول على إذن في sessionStorage أو localStorage ، حسب احتياجاتنا. في الحالة الأولى ، يتم تخزين البيانات حتى يكمل المستخدم الجلسة أو يغلق المتصفح ، في الحالة الثانية ، سيتم تخزين البيانات في المتصفح لفترة غير محدودة حتى يتم مسح localStorage لسبب ما.

وظيفة لحفظ الرمز المميز في sessionStorage:


 function saveToken(token) { sessionStorage.setItem('tokenData', JSON.stringify(token)); } 

وظيفة لتلقي رمز مميز:


 function getTokenData(login, password) { return fetch('api/auth', { method: 'POST', credentials: 'include', headers: { 'Accept': 'application/json', 'Content-Type': 'application/json', }, body: JSON.stringify({ login, password, }), }) .then((res) => { if (res.status === 200) { const tokenData = res.json(); saveToken(JSON.stringify(tokenData)); //     sessionStorage,   ,   return Promise.resolve() } return Promise.reject(); }); } 

وبالتالي ، تلقينا رمزًا مميزًا بالحقول "access_token" و "refresh_token" و "expires_in" وحفظناه في sessionStorage لاستخدامه مرة أخرى.

تحديث الرمز


الرمز المميز الذي تلقيناه سابقًا له عمر محدود ، والذي تم تعيينه في حقل "expires_in" . بعد انتهاء فترة صلاحيته ، لن يتمكن المستخدم من تلقي بيانات جديدة عن طريق إرسال هذا الرمز المميز في الطلب ، لذلك تحتاج إلى الحصول على رمز مميز جديد.

يمكننا الحصول على الرمز المميز بطريقتين: الطريقة الأولى هي تسجيل الدخول مرة أخرى عن طريق إرسال اسم المستخدم وكلمة المرور إلى الخادم. ولكن هذا لا يناسبنا ، لأن إجبار المستخدم على إعادة إدخال بيانات التفويض في كل مرة بعد فترة زمنية معينة هو خطأ - يجب أن يتم ذلك تلقائيًا. ولكن تخزين زوج تسجيل الدخول / كلمة المرور في مكان ما في الذاكرة للإرسال التلقائي غير آمن ، ولهذا السبب نحن بحاجة إلى تحديث_token ، والذي تم استلامه مسبقًا مع access_token وتخزينه في sessionStorage. من خلال إرسال هذا الرمز المميز إلى عنوان آخر يوفره api ، يمكننا الحصول على رمز جديد "جديد" في الرد.

وظيفة لتحديث الرمز


 function refreshToken(token) { return fetch('api/auth/refreshToken', { method: 'POST', credentials: 'include', headers: { 'Accept': 'application/json', 'Content-Type': 'application/json', }, body: JSON.stringify({ token, }), }) .then((res) => { if (res.status === 200) { const tokenData = res.json(); saveToken(JSON.stringify(tokenData)); //      sessionStorage,   ,   return Promise.resolve(); } return Promise.reject(); }); } 

باستخدام الرمز أعلاه ، أعادنا كتابة الرمز المميز في sessionStorage والآن يمكننا إرسال الطلبات إلى api بطريقة جديدة.

خلق وظيفة المجمع


الآن نقوم بإنشاء وظيفة تضيف بيانات التفويض إلى رأس الطلب ، وإذا لزم الأمر ، قم بتحديثها تلقائيًا قبل تقديم الطلب.

نظرًا لأنه في حالة انتهاء صلاحية الرمز المميز ، سنحتاج إلى طلب رمز مميز جديد ، فستكون وظيفتنا غير متزامنة. لهذا سوف نستخدم بناء المتزامن / انتظار.

وظيفة التفاف


 export async function fetchWithAuth(url, options) { const loginUrl = '/login'; // url    let tokenData = null; //    tokenData if (sessionStorage.authToken) { //   sessionStorage  tokenData,    tokenData = JSON.parse(localStorage.tokenData); } else { return window.location.replace(loginUrl); //   ,       } if (!options.headers) { //     headers,    options.headers = {}; } if (tokenData) { if (Date.now() >= tokenData.expires_on * 1000) { //        try { const newToken = await refreshToken(tokenData.refresh_token); //  ,      refresh_token saveToken(newToken); } catch () { //   -   ,       return window.location.replace(loginUrl); } } options.headers.Authorization = `Bearer ${tokenData.token}`; //    headers  } return fetch(url, options); //   ,       headers } 

باستخدام الرمز أعلاه ، أنشأنا وظيفة ستضيف رمزًا مميزًا للطلبات في واجهة برمجة التطبيقات. باستخدام هذه الوظيفة ، يمكننا استبدال عمليات جلب في الاستعلامات التي نحتاج إليها ، وحيثما يكون الترخيص مطلوبًا ، ولهذا لا نحتاج إلى تغيير بناء الجملة أو إضافة أي بيانات أخرى إلى الوسائط.
يكفي فقط "استيراده" إلى ملف واستبداله بجلبه القياسي.

 import fetchWithAuth from './api'; function getData() { return fetchWithAuth('api/data', options) } 

Source: https://habr.com/ru/post/ar456188/


All Articles