title: Ionic 3 : verify if token has expired on nodeJS Server
body: <p>I'm building an ionic 2 app with NodeJS API, in the server side I'm using jsonwebtoken to create the token after login success and save it on localStorage in the client side. my problem is how to compare and check if the token is still valid after the expireIN time ! </p>
  
  <p>here is the server route side code : </p>
  
  <pre><code>//   :::::: G E T   T H E   P A C K A G E   W E   N E E D : :  :   :    :     :        :          :
  
  var express = require('express');
  var app = express();
  var bodyParser = require('body-parser');
  var morgan = require('morgan');
  var mongoose = require('mongoose');
  var cors=require('cors'); 
  var jwt = require('jsonwebtoken'); // used to create, sign, and verify tokens
  var config = require('./config'); // get our config file
  // ─── GET an instance of the router for api routes ────────────────────────────────────────────────────────────────────────
  var apiRoutes = express.Router();
  var users =require('./app/routes/users'); 
  //
  // ────────────────────────────────────────────── II ──────────────────────────────────────────────────────────────────────
  //   :::::: CONFIGURATION : :  :   :    :     :        :          :
  var port = process.env.PORT || 1991; // used to create, sign, and verify tokens
  mongoose.connect(config.database, { useMongoClient: true }); // connect to database
  app.set('superSecret', config.secret); // secret variable
  
  //
  // ────────────────────────────────────────────── III ──────────────────────────────────────────────────────────────────────
  //   :::::: USE BODY PARSER SO WE CAN GET INFO FROM POST AND/OR URL PARAMETERS : :  :   :    :     :        :          :
  app.use(bodyParser.urlencoded({ extended: true }));
  app.use(bodyParser.json());
  //   :::::: USE MORGAN TO LOG REQUESTS TO THE CONSOLE: :  :   :
  
  app.use(morgan('dev'));
  app.use(cors());
  
  
  // ──────────────────────────────────────────────────────────────
  //   :::::: R O U T E S : :  :   :    :     :        :          :
  // ──────────────────────────────────────────────────────────────
  // ───  A P I ROUTES ────────────────────────────────────────
  
  
  
  //   :::::: MIDDLEWARE to secure route begin with /api: :  :   :  
  
  apiRoutes.use(function(req, res, next) {
  
          console.log('hah');
      var token = req.body.token || req.query.token || req.headers['x-access-token'];
  
  
      if (token) {
      // verifies secret and checks exp
          jwt.verify(token, app.get('superSecret'), function(err, decoded) {
              console.log([err,decoded]);
              if (err) { //failed verification.
                  return res.json({"error": true, success:false, message:'Faild to authenticate token'});
              }
              req.decoded = decoded;
              next(); //no error, proceed
          });
      } else {
          // forbidden without token
          return res.status(403).send({
              success: false,
              message: 'No token provided.'
          });
      }
  });
  
  apiRoutes.get('/', function(req, res) {
      res.json({ message: 'Welcome to the coolest API on earth!' });
  });
  app.use('/api', apiRoutes);
  app.use('/user', users);
  
  // ──────────────────────────────────────────────────
  //   :::::: S T A R T the server: :  :   :    :     :          
  
  app.listen(port);
  console.log('Magic happens at http://localhost:' + port);
  </code></pre>
  
  <p>user route : </p>
  
  <pre><code>const express=require('express'); 
  const router=express.Router();
  const passport= require('passport'); 
  const jwt=require('jsonwebtoken');  
  
  var userRoutes = express.Router();
  var config = require('../../config'); // get our config file
  var User = require('../../app/models/User'); // get our mongoose model
  
  
  //
  // ─── ROUTE TO REGISTER USER ──────────────────────────────────────────────────────────────────────
  //
  userRoutes.post('/signup', function(req, res) {
      if (!req.body.email ||  !req.body.password || !req.body.firstname || !req.body.lastname || !req.body.gender || !req.body.isTrainer) {
          res.json({ success: false, msg: 'set up required fields' });
      } else {
          var newUser = new User({
              email:      req.body.email,
              password:   req.body.password,
              firstname:  req.body.firstname,
              lastname:   req.body.lastname,
              gender:     req.body.gender,
              isTrainer:  req.body.isTraine   
          });
          User.find({ email: req.body.email}, function(err, user){
              if (err) {
                  res.send({ success: false, msg:'authentication error'})
              }
              else if (user.length != 0) {
                  res.send({success: false, msg:'Email already exists'})
                  console.log(user);
              }else {
                  // save the user
                  newUser.save(function(err) {
                      if (err) {
                          console.log(err);       
                      }else {
                          res.send({ success: true, msg: 'Your account created successfully! ' });    
                      }
  
               });
              }
          })
  
      }
  });
  
  userRoutes.post('/signin', function(req, res) {
      User.findOne({
          email: req.body.email
      }, function(err, user) {
          if (err) throw err;
  
          if (!user) {
              res.send({ success: false, msg: 'Check your email' });
          } else {
              // check if password matches
              user.comparePassword(req.body.password, function(err, isMatch) {
                  if (isMatch &amp;&amp; !err) {
                      // if user is found and password is right create a token
                      var token = jwt.sign(user, config.secret,{
                          expiresIn: 30
                      });
  
                      // return the information including token as JSON
                      res.json({
                          success: true,
                          token: token,
                          username: user.username
                      });
                  } else {
                      res.send({ success: false, msg: 'Check your password!' });
                  }
              });
          }
      });
  });
  
  userRoutes.get('/users', function(req, res) {
      User.find({}, function(err, users) {
          res.json(users);
      });
  });
  module.exports= userRoutes; 
  </code></pre>
  
  <p>ionic authProvider : </p>
  
  <pre><code>import { Injectable} from '@angular/core';
  import {Http, Headers} from '@angular/http';
  import { Storage } from '@ionic/storage';
  import 'rxjs/add/operator/map';
  
  @Injectable()
  export class AuthenticationProvider{
      public token: any;
      isLoggedin: boolean;
  
     constructor(public http: Http, public storage: Storage) {
         this.http = http;
         this.isLoggedin = false;
         this.token = null;
     }
  
     //check authentication to /api
  
      checkAuthentication(){
          return new Promise((resolve, reject)=&gt; {
              //load token if exist
              this.storage.get('token').then((value)=&gt; {
                  this.token = value;
                  let headers = new Headers();
                  headers.append('Authorisation', this.token);
  
                  this.http.get('http://localhost:1991/api', {headers:headers})
                          .subscribe(res =&gt; {
                              resolve(res);
                      }, (err) =&gt; {
                              reject(err);
                  });
              });
          });
      }
  
      storeUserCredentials(token) {
          window.localStorage.setItem('token', token);
          this.useCredentials(token);
      }
  
      loadUserCredentials() {
          var token = window.localStorage.getItem('token');
          this.useCredentials(token);
      }
  
      destroyUserCredentials() {
          this.isLoggedin = false;
          this.token = null;
          window.localStorage.removeItem('token');
      }
  
       useCredentials(token) {
          this.isLoggedin = true;
          this.token = token;
      }
  
      isLogged(){
          if(window.localStorage.getItem('token')){
            return true
          }else{
            return false;
          }
      }
  
      signin(usercreds){
          let headers = new Headers();
          headers.append('Content-Type', 'application/json');
          return new Promise((resolve,reject) =&gt; {
              this.http.post('http://localhost:1991/user/signin', usercreds, {headers: headers}).subscribe( data =&gt; {
                  if(data.json().success){
                      this.storeUserCredentials(data.json().token);
                      resolve(true);
                  }
                  else
                      reject(data.json().msg); 
              });
          }); 
      }
  
      signup(details){
          let headers = new Headers();
          headers.append('content-Type', 'application/json');
          return new Promise((resolve,reject) =&gt;{
              this.http.post('http://localhost:1991/user/signup', details, {headers: headers}).subscribe(data =&gt;{
                  if(data.json().success){
                      resolve(true)
                  }else{
                      reject(data.json().msg);
                  }
              });
          });
      }
  
      logout(){
          this.destroyUserCredentials();
      }
  
  }
  </code></pre>
  
  <p>ionic login.ts </p>
  
  <pre><code>import { Component, trigger, state, style, transition, animate, keyframes } from '@angular/core';
  import { AuthenticationProvider } from '../../providers/authentication/authentication';
  import { NavController,AlertController, NavParams, LoadingController } from 'ionic-angular';
  import { SignupPage } from '../signup/signup';
  import { MainPage } from '../main/main';
  
  /**
   * Generated class for the LoginPage page.
   *
   * See http://ionicframework.com/docs/components/#navigation for more info
   * on Ionic pages and navigation.
   */
  
  @Component({
    selector: 'page-login',
    templateUrl: 'login.html',
  
    animations: [
  
      //For the logo
      trigger('flyInBottomSlow', [
        state('in', style({
          transform: 'translate3d(0,0,0)'
        })),
        transition('void =&gt; *', [
          style({transform: 'translate3d(0,2000px,0'}),
          animate('2000ms ease-in-out')
        ])
      ]),
  
      //For the background detail
      trigger('flyInBottomFast', [
        state('in', style({
          transform: 'translate3d(0,0,0)'
        })),
        transition('void =&gt; *', [
          style({transform: 'translate3d(0,2000px,0)'}),
          animate('1000ms ease-in-out')
        ])
      ]),
  
      //For the login form
      trigger('bounceInBottom', [
        state('in', style({
          transform: 'translate3d(0,0,0)'
        })),
        transition('void =&gt; *', [
          animate('2000ms 200ms ease-in', keyframes([
            style({transform: 'translate3d(0,2000px,0)', offset: 0}),
            style({transform: 'translate3d(0,-20px,0)', offset: 0.9}),
            style({transform: 'translate3d(0,0,0)', offset: 1}) 
          ]))
        ])
      ]),
  
      //For login button
      trigger('fadeIn', [
        state('in', style({
          opacity: 1
        })),
        transition('void =&gt; *', [
          style({opacity: 0}),
          animate('1000ms 2000ms ease-in')
        ])
      ])
    ]
  })
  export class LoginPage {
  
    logoState: any = "in";
    cloudState: any = "in";
    loginState: any = "in";
    formState: any = "in";
   usercreds = {
        email: '',
        password: '' 
      };
  
    loadinglogin: any;
    loadingfailed: any;
    fbUserData: any;
    constructor(private alertCtrl: AlertController, public navCtrl: NavController, public navParams: NavParams, public authenticationProvider: AuthenticationProvider, public loadingCtrl: LoadingController) {
      this.navCtrl = navCtrl;
    }
  
    ionViewDidLoad() {
  
      this.showLoaderOnlogin();
      this.authenticationProvider.checkAuthentication().then((res) =&gt; {
          this.loadinglogin.dismiss();
          }, (err) =&gt; {
          console.log("Not already authorized");
          this.loadinglogin.dismiss();
      });
      console.log('ionViewDidLoad LoginPage');
    }
  
    login(usercreds){    
      this.authenticationProvider.signin(usercreds).then(data =&gt; {
  
          this.navCtrl.setRoot(MainPage);  
  
      }).catch(msg =&gt; {
        this.presentAlert(msg);
      });
    }
  
    opensignUpPage(){
      this.navCtrl.push(SignupPage,{}, {animate: true, direction: 'back'} );
    }
  
    showLoaderOnlogin(){
      this.loadinglogin = this.loadingCtrl.create({
        content: 'Authenticating...',
        showBackdrop: true,
      });
      this.loadinglogin.present();
    }
  
    presentAlert(msg) {
    let alert = this.alertCtrl.create({
      title: 'Authentication failed',
      message:msg,
      buttons: ['Ok'],
      cssClass:'alert-faild'
    });
      alert.present();
    }  
  
  
  }
  </code></pre>
  
  <p>the token is stored successfully in the local storage and I want to check if it's not still valid delete it from localStorage and setRoot page to login page and if still valid let it saved and setRoot page to main page.</p>