سيتم تسجيل الخروج logout عبر هذه المراحل
-مسح كود token من الداكرة الداخلية للتطبيق (local storage)
- انشاء حدث جديد يقوم بتغيير القائمة الرئيسية menu الى قائمة الزوار
- تحويل المستخدم الى الصفحة الرئيسية بعد تسجيل خروجه
لا يمكنك قتل كود token من جهة الخادم يدويا. ولكن بامكانك تحديد عمره أو بمعنى اخر مدة صلاحيته كما وضحنا سابقا.
ادا كنت ترغب بقتل كود token فان الخيار الأفضل هو أن تترك اثر لاخر تسجيل خروج بقاعدة البيانات ثم تقوم بمقارنة تاريخ اخر خروج مع مدة صلاحية token المشفرة في JWT ، وإذا لم تتطابق تواريخ البيانات مع تسجيل خروج المستخدم فتمنعه من الدخول وتعتبر كود توكن القديم غير صالح (دون تحديث التاريخ في هذه الحالة). .. طبعا نحن لسنا بصدد عمل كل هذا لكي نتجنب تضيع الوقت . تستطيع برمجتها ان شئت فقد منحتك الفكرة البرمجية
يجب عليك دائمًا تحديد وقت انتهاء معقول في JWT. ولنقل مثلا ليوم واحد أو يومين. تجنب الرموز الدائمة الأبدية
مثال عن تشفير رمز token صالح لمدة 5 ثوان
{
"sub": "1234567890",
"name": "John Doe",
"iat": 1516234022, // القيمة بالميلي ثانية / توقيت انشاء كود التوكن
"exp": 1516239022 // القيمة بالميلي ثانية /انتهاء الصلاحية
}
تفاصيل الدرس
نقوم بالتوجه نحو ملف app.component.ts ونضيف كود بداخل ال switch في دالة openPage حيث يقوم بمناداة دالة logout من ملف الخدمة والتي بدورها تقوم بمسح الرمز token من الداكرة الداخلية للتطبيق ... ثم يتم توجيه المستخدم نحو الصفحة الرئيسية
openPage(page) {
// Reset the content nav to have just this page
// we wouldn't want the back button to show in this scenario
switch (true) {
case ((page.title == 'Logout')): { // في حال الضغط على زر تسجيل الخروج
this.authentication.logout(); // call logout logic method
this.events.publish('user:logout'); //logout event
this.nav.setRoot(HomePage);
}
break;
default: {
this.nav.setRoot(page.component); // التوجيه الى الصفحة المعنية
//ملاحظة
// setRoot تقوم بتحويل الى صفحة جديدة دون امكانية الرجوع للصفحة السابقة
// push تقوم بتحويلك الى الصفحة الجديدة مع امكانية الرجوع للصفحة السابقة وتضع لك ايقونة الرجوع في اعلى الصفحة
}
break;
}
}
ليصبح الملف بهذا الشكل
import { Component, ViewChild } from '@angular/core';
import { Events,Nav, Platform,MenuController } from 'ionic-angular';
import { StatusBar } from '@ionic-native/status-bar';
import { SplashScreen } from '@ionic-native/splash-screen';
import { HomePage } from '../pages/home/home';
import { ProfilePage } from '../pages/profile/profile';
import { LoginPage } from '../pages/login/login';
import { RegisterPage } from '../pages/register/register';
import { CartPage } from '../pages/cart/cart';
import { AuthenticationProvider } from '../providers/authentication/authentication';
@Component({
templateUrl: 'app.html'
})
export class MyApp {
@ViewChild(Nav) nav: Nav;
rootPage: any = HomePage; // الصفحة الرئيسية التي ينطلق منها التطبيق عند التشغيل
pages: Array<{title: string, component: any, icon:string}>;
accountPages: Array<{title: string, component: any, icon:string}>;
userButtons: Array<{title: string, component: any , color:string , icon:string}>;
guestButtons: Array<{title: string, component: any , color:string , icon:string}>;
constructor(
public platform: Platform,
public statusBar: StatusBar,
public splashScreen: SplashScreen,
public events: Events,
public menu: MenuController,
public authentication: AuthenticationProvider,
) {
this.initializeApp();
this.listenToLoginEvents(); // دالة تفعيل احد القوائم في حال اكتشاف حدث معين
// قائمة الأزرار الاعتيادية التي سيتم عرضها بشكل دائم
this.pages = [
{ title: 'Home', component: HomePage ,icon:'home'},
{ title: 'My Cart', component: CartPage,icon:'cart' },
{ title: 'About Us', component: HomePage,icon:'cafe' },
{ title: 'Find Us', component: HomePage ,icon:'map'},
{ title: 'Settings', component: HomePage ,icon:'build'},
];
// قائمة الازرار التي تضاف الى مكونات القائمة الجانبية في حال تم تسجيل الدخول
this.accountPages = [
{ title: 'Orders', component: HomePage ,icon:'clipboard'},
{ title: 'Edit Account', component: HomePage ,icon:'create'},
];
// الازرار العلوية الملونة بالازرق الفاتح والاخضر
//بالنسبة للزوار
this.guestButtons = [
{ title: 'Register', component: RegisterPage,color:'primary',icon:'contact' },
{ title: 'Login', component: LoginPage , color:'secondary',icon:'lock' },
];
// بالنسبة للمستخدم الدي قام بتسجيل الدخول
this.userButtons = [
{ title: 'Account', component: ProfilePage,color:'primary',icon:'contact' },
{ title: 'Logout', component: HomePage , color:'secondary',icon:'log-out' },
];
} // .end constructor
initializeApp() {
this.platform.ready().then(() => {
// Okay, so the platform is ready and our plugins are available.
// Here you can do any higher level native things you might need.
this.statusBar.styleDefault();
this.splashScreen.hide();
});
}
listenToLoginEvents() {
this.events.subscribe('user:login', () => { // التنصت على حدث تسجيل الدخول
this.enableMenu(true);
});
this.events.subscribe('user:logout', () => { // التنصت على حدث تسجيل الخروج
this.enableMenu(false);
});
}
enableMenu(loggedIn: boolean) {
this.menu.enable(loggedIn, 'user-menu'); // ID تفعيل القائمة المشار اليها بهدا المؤشر
this.menu.enable(!loggedIn, 'guest-menu'); // ID تفعيل القائمة المشار اليها بالمؤشر
}
// exp : id="user-menu"
openPage(page) {
// Reset the content nav to have just this page
// we wouldn't want the back button to show in this scenario
switch (true) {
case ((page.title == 'Logout')): { // في حال الضغط على زر تسجيل الخروج
this.authentication.logout(); // call logout logic method
this.events.publish('user:logout'); //logout event
this.nav.setRoot(HomePage);
}
break;
default: {
this.nav.setRoot(page.component); // التوجيه الى الصفحة المعنية
//ملاحظة
// setRoot تقوم بتحويل الى صفحة جديدة دون امكانية الرجوع للصفحة السابقة
// push تقوم بتحويلك الى الصفحة الجديدة مع امكانية الرجوع للصفحة السابقة وتضع لك ايقونة الرجوع في اعلى الصفحة
}
break;
}
}
}
بملف الخدمة src/providers/authentication/authentication.ts
نضيف دالة logout
logout(){
return this.storage.remove('token');
}