Node + Express+ Mysql + Jsonwebtoken 实现登陆token检验

2,128 阅读3分钟

安装

npm install body-parser -S
npm install express --save
npm install mysql -S
npm install express-jwt -S
npm install jsonwebtoken -S

简单服务

创建一个空项目,npm init -y 加载 package.json 文件。 在项目下创建app.js, 开启服务:

const express = require('express')
const bodyParser = require('body-parser')
const expressJwt = require('express-jwt')
const token = require('./jwt')
const userDao = require('./userDao')
const loginrecordDao = require('./loginrecordDao')
const app = express()

// 解析 post body
app.use(bodyParser.urlencoded({ extended: false }))
app.use(bodyParser.json())


//  开启 CORS 跨域 
app.all('*',function (req, res, next) {
    res.header('Access-Control-Allow-Origin', '*');
    res.header('Access-Control-Allow-Headers', 'Content-Type, Content-Length, Authorization, Accept, X-Requested-With , yourHeaderFeild');
    res.header('Access-Control-Allow-Methods', 'PUT, POST, GET, DELETE, OPTIONS');
  
    if (req.method == 'OPTIONS') {
      res.send(200); /让options请求快速返回/
    }
    else {
      next();
    }
});

// 创建一个接口调试

app.get('/hello',function(req, res){
    res.send('hello')
})

// 中间件  处理 404 错误
app.use(function ( req, res, next) {
    res.status(404).send('Not found!')
})
// 中间件 处理 500 错误
app.use(function (err, req, res, next) {
    console.error(err.stack)
    res.status(500).send('Something broke!')
  })

app.listen(5000, function(){
    console.log('127.0.0.1:5000 running ')
})

node ./app.js 运行 ,访问 http://127.0.0.1:5000/hello,有数据即成功

连接Mysql

创建数据表

CREATE TABLE `user` (
  `userid` varchar(40) NOT NULL,
  `username` varchar(255) DEFAULT NULL,
  `email` varchar(255) DEFAULT NULL,
  `password` varchar(255) DEFAULT NULL,
  `createtime` datetime DEFAULT NULL,
  `updatetime` datetime DEFAULT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

连接

创建 mysqlconnect.js

var mysql   = require('mysql');
var connection = mysql.createConnection({
  host     : 'localhost', 
  user     : 'root',
  password : '123456.',
  database : 'vvweb'
});
 
connection.connect();

module.exports = connection

然后添加几条数据测试用。

操作数据

创建 userDao.js

const mysqlConnection = require('./mysqlconnect')

const  onSelectOnlyUser = function(params){
    return new Promise(function(resolve, reject){
        
        let  selectSql = 'SELECT userid,username,email,DATE_FORMAT(createtime,\'%Y-%m-%d %h:%i:%s\') AS createtime FROM user WHERE email = ? AND password = ? ';
        let  selectSqlParams = [params.email, params.password];
        //更新
        mysqlConnection.query(selectSql,selectSqlParams,function (err, result) {
                if(err){
                    console.log('[INSERT ERROR] - ',err.message);
                    reject(err)
                    return;
                }        
        
            console.log('--------------------------SELECT----------------------------');
            //console.log('INSERT ID:',result.insertId);        
            console.log('SELECT ID:',result);        
            console.log('-----------------------------------------------------------------\n\n');  
            resolve(result)
        });
 

    })
}

module.exports ={
    onSelectOnlyUser 
}

测试

const userDao = require('./userDao')
 userDao.onSelectOnlyUser({ email : '111' , password: '123456' }).then((result)=>{
       console.log('-------- onSelectOnlyUser----', result)
    }).catch(err=>{
        console.log('-------- onSelectOnlyUser----', err)
    })

使用JWT

操作方法

创建 jwt.js

const jwt = require('jsonwebtoken');
const Token = {
   //  生成
  encrypt:function(data,time){ //data加密数据 ,time过期时间  60 * 30  (30分)
    return jwt.sign(data, 'wtechtec', {expiresIn: time })
  },
  // 解析
  decrypt:function(token){
    try {
      let data = jwt.verify(token, 'token');
      return {
        token:true
      };
    } catch (e) {
      return {
        token:false,
        data:e
      }
    }
  }
}
module.exports = Token;

使用

  const token = require('./jwt')
   let authorization =  token.encrypt( {data:rel.userid }, 60 * 30)
   console.log('-------- authorization ----', authorization )

有数据说明已成功

整合登陆 授权

创建 appfinally.js

const express = require('express')
const bodyParser = require('body-parser')
const expressJwt = require('express-jwt')
const token = require('./jwt')
const userDao = require('./userDao')
const loginrecordDao = require('./loginrecordDao')
const app = express()
// parse application/x-www-form-urlencoded
app.use(bodyParser.urlencoded({ extended: false }))
 
// parse application/json
app.use(bodyParser.json())

app.all('*',function (req, res, next) {
    res.header('Access-Control-Allow-Origin', '*');
    res.header('Access-Control-Allow-Headers', 'Content-Type, Content-Length, Authorization, Accept, X-Requested-With , yourHeaderFeild');
    res.header('Access-Control-Allow-Methods', 'PUT, POST, GET, DELETE, OPTIONS');
  
    if (req.method == 'OPTIONS') {
      res.send(200); /让options请求快速返回/
    }
    else {
      next();
    }
});

app.use(expressJwt({
    secret: 'token',  // 签名的密钥 或 PublicKey 
    algorithms: ['HS256']
  }).unless({
    path: ['/signIn', '']  // 指定路径不经过 Token 解析
}))
  
  // 创建一个接口调试

app.get('/hello',function(req, res){
    res.send('hello')
})


app.post('/signIn', function(req, res){
    userDao.onSelectOnlyUser(req.body).then((result)=>{
        if (result.length === 0 ||  result.length >= 2) {
            res.status(201).send(result)
        } else {
            console.log('-------- signIn ----')
            let rel = result[0]
            let authorization =  token.encrypt( {data:rel.userid })
            rel['authorization'] =  authorization
            console.log(rel)
      
        }
        
    }).catch(err=>{
        res.send(err)
    })
    
})





app.use(function ( req, res, next) {
    res.status(404).send('Not found!')
})

app.use(function (err, req, res, next) {
    if (err.name === 'UnauthorizedError') {   
      res.status(401).send('token 过期')
      return 
    }
})

app.use(function (err, req, res, next) {
    console.error(err.stack)
    res.status(500).send('Something broke!')
  })

app.listen(5000, function(){
    console.log('127.0.0.1:5000 running ')
})

app.use(expressJwt({
    secret: 'token',  // 签名的密钥 或 PublicKey 
    algorithms: ['HS256']
  }).unless({
    path: ['/signIn', '']  // 指定路径不经过 Token 解析
}))

secret 的参数 要与 jwt.js 中 第二个参数一样,不然无效token

   //  生成
  encrypt:function(data,time){ //data加密数据 ,time过期时间  60 * 30  (30分)
    return jwt.sign(data, 'token', {expiresIn: time })
  },