Ionic 3:验证nodeJS Server上的令牌是否已过期

时间:2017-07-23 16:05:32

标签: javascript node.js api ionic-framework token

我正在使用NodeJS API构建离子2应用程序,在服务器端我使用jsonwebtoken在登录成功后创建令牌并将其保存在客户端的localStorage中。我的问题是如何比较并检查令牌在expireIN时间后是否仍然有效!

这是服务器路由端代码:

//   :::::: 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);

用户路线:

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 && !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; 

ionic authProvider:

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)=> {
            //load token if exist
            this.storage.get('token').then((value)=> {
                this.token = value;
                let headers = new Headers();
                headers.append('Authorisation', this.token);

                this.http.get('http://localhost:1991/api', {headers:headers})
                        .subscribe(res => {
                            resolve(res);
                    }, (err) => {
                            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) => {
            this.http.post('http://localhost:1991/user/signin', usercreds, {headers: headers}).subscribe( data => {
                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) =>{
            this.http.post('http://localhost:1991/user/signup', details, {headers: headers}).subscribe(data =>{
                if(data.json().success){
                    resolve(true)
                }else{
                    reject(data.json().msg);
                }
            });
        });
    }

    logout(){
        this.destroyUserCredentials();
    }

}

ionic login.ts

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 => *', [
        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 => *', [
        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 => *', [
        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 => *', [
        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) => {
        this.loadinglogin.dismiss();
        }, (err) => {
        console.log("Not already authorized");
        this.loadinglogin.dismiss();
    });
    console.log('ionViewDidLoad LoginPage');
  }

  login(usercreds){    
    this.authenticationProvider.signin(usercreds).then(data => {

        this.navCtrl.setRoot(MainPage);  

    }).catch(msg => {
      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();
  }  


}

令牌已成功存储在本地存储中,我想检查它是否仍然有效将其从localStorage和setRoot页面删除到登录页面,如果仍然有效则将其保存并将setRoot页面保存到主页面。

1 个答案:

答案 0 :(得分:0)

jwt令牌在构建时没有到期功能。你可以信任一个jwt令牌。但如果你还想要这样的话。然后你可以在你用来编码innto jwt token的对象中添加一个时间字段。

   profile = {'field1':'value1', expire':'time'}
   result.token= jwt.encode(profile, config.secret);

当您在此时将令牌解码回对象时,查看该对象是否已过期。

  jwt.verify(token, app.get('superSecret'), function(err, decoded) {
        check decoded.expire  here.
  }