nodejs JWT jsonwebtoken学习笔记

文章目录

    • 文章参考
    • jsonwebtoken生成token和校验token

文章参考

  1. jsonwebtoken npm
  2. jsonwebtoken 介绍

jsonwebtoken生成token和校验token

  1. controller 接收用户的请求
var express = require('express')
var connection = require('../common/mysqlConn')
var userService = require('../service/userService')
var jwtTools = require('../common/jwtTools')
// 用来缓存token
const tokenCache = {
     }
var router = express.Router()
// 判断用户是否存在
router.post('/login', function (req, res, next) {
     
  const pageObj = req.body
  var currentPage = parseInt(pageObj.currentPage) - 1
  let paramObj = {
     
    username: pageObj.username,
    pwd: pageObj.pwd,
  }
  userService.loginUser(paramObj, function (err, results, fields) {
     
    if (results.length > 0) {
     
      let token = jwtTools.createTokenByLoginInfo(results[0])
      tokenCache[token] = token
      res.json({
     
        state: 1, // 1表示状态成功, 0表示失败
        user: results[0],
        token,
      })
    } else {
     
      res.json({
     
        state: 0, // 1表示状态成功, 0表示失败
        message: '用户不存在',
      })
    }
  })
})

// 根据token 获取用户信息
router.post('/currenuser', function (req, res, next) {
     
  const headerObj = req.headers
  const tokenStr = headerObj.token
  if (!tokenStr) {
     
    res.json({
     
      state: 0, // 1表示状态成功, 0表示失败
      message: '没有token',
    })
  } else {
     
    if (tokenCache[tokenStr]) {
     
      jwtTools.verifyToken(tokenStr).then((tokenResult) => {
     
        if (tokenResult.status) {
     
          res.json({
     
            state: 1, // 1表示状态成功, 0表示失败
            user: tokenResult.code,
          })
        } else {
     
          res.json({
     
            state: 0, // 1表示状态成功, 0表示失败
            message: 'token 已过期',
          })
        }
      })
    } else {
     
      res.json({
     
        state: 1, // 1表示状态成功, 0表示失败
        message: '无效token',
      })
    }
  }
})
  1. jwtTools.js 创建token,根据token获取用户信息
const jwt = require('jsonwebtoken') // 使用jwt签名

const tokenConfig = {
     
  jwtsecret: '1qaz2wsx',
}

// 使用用户JSON对象生成token
const createTokenByLoginInfo = function (userInfo) {
     
  let tempUser = userInfo
  console.log(JSON.parse(JSON.stringify(tempUser)))
  let token = jwt.sign(JSON.parse(JSON.stringify(tempUser)), tokenConfig.jwtsecret, {
     
    expiresIn: 60 * 60 * 24, // 授权时效24小时
  })
  return token
}

// 根据token 获取用户JSON对象
const verifyToken = function (token) {
     
  return new Promise((resolve, reject) => {
     
    jwt.verify(token, tokenConfig.jwtsecret, function (err, decoded) {
     
      if (err) {
     
        resolve({
     
          status: false,
          message: '无效的token.',
        })
      } else {
     
        resolve({
     
          status: true,
          message: '有效的token.',
          code: decoded,
        })
      }
    })
  })
}

// 认证头部请求是否带有token
const authenticateJWT = (req, res, next) => {
     
  const authHeader = req.headers.authorization
  if (!authHeader) {
     
    res.sendStatus(401)
    return 
  }

  const token = authHeader.split(' ')[1]
  jwt.verify(token, process.env.ACCESS_TOKEN_SECRET, (err, user) => {
     
    if (err) {
     
      res.sendStatus(403)
      return 
    }
    req.user = user
    next()
  })
}

module.exports = {
     
  authenticateJWT,
  createTokenByLoginInfo,
  verifyToken,
}
  1. JWT 统一拦截, 定义路由,在非登录界面,需要验证token是否已经带入
const app = express();
const jwtTools = require('./util/jwtTools')
const server = http.createServer(app)

// 允许跨域 /
app.all('*', function(req, res, next) {
     
  console.log(req.headers.origin)
  console.log(req.environ)
  res.header("Access-Control-Allow-Origin", req.headers.origin);
  // res.header("Access-Control-Allow-Origin", '*');
  res.header("Access-Control-Allow-Headers", "Content-Type,Content-Length, Authorization, Accept,X-Requested-With");
  res.header("Access-Control-Allow-Methods","PUT,POST,GET,DELETE,OPTIONS");
  res.header("Access-Control-Allow-Credentials","true");
  res.header("X-Powered-By",' 3.2.1')
  if(req.method === "OPTIONS") res.send(200);/*让options请求快速返回*/
  else  next();
});

// 请求头验证token /
app.all('*', function(req, res, next) {
     
  // 当请求不为登录的时候,就需要检测 token
  if (req.path !== '/api/users/login' && req.path !== '/api/users') {
     
    jwtTools.authenticateJWT(req, res, next)
  } else {
     
    next()
  }
});
  1. 要先允许跨域,然后再验证头部的token,如果颠倒,第一次option请求就会被拦截,则永远都不会成功
  2. 关于跨域的问题,参考 nodejs express 允许跨域设置
  1. 客户端
    在请求头中加入 Authorization 验证类型为 Bearer
{
     
	header: {
     
		Authorization: 'Bearer jwtTokenStr'
	}
}

注意 Bearer 和 jwtTokenStr 之间是有空格的

你可能感兴趣的:(nodejs,npm,express,gulp)