node使用jsonwebtoken生成token与验证是否过期
阅读原文时间:2023年08月10日阅读:1

场景

我们可以使用 cookie,session,token 来做鉴权。
下面我们来看一下,
如何使用 token 来做鉴权

jwt.sign 的简单介绍

npm install jsonwebtoken 下载

使用 jsonwebtoken 生成token的基本语法。
jwt.sign(payload, secretOrPrivateKey, [options, callback])
第1个参数 payload:可以是表示有效 JSON 的对象文本、缓冲区,字符串。
需要注意的是:如果不是缓冲区或字符串,使用 JSON.stringify
下面我们使用对象文本,就不需要使用 JSON.stringify。

第2个参数 secretOrPrivateKey: 是一个字符串(utf-8编码)、缓冲区、对象。
就是说是加密数据。

options:包含的其他选项,如过期时间,
它的选项有:expiresIn 过期时间,如果是数字,单位就是秒。
algorithm: HS256 (默认的算法)

callback:回调函数,包含返回来的错误

使用 jsonwebtoken 生成token

// 生成的token。 expiresIn 数值单位默认是秒s
//expiresIn也可以添加为 expiresIn:'10h' | '10d'
let createToken = jwt.sign({
  data: 'jiamideshuju'
}, 'lingpai', { expiresIn: 3 });
//  expiresIn: 3 表示的是有效时间是3s。
console.log('生成的token', createToken)

查看生成的token是否过期
// 生成的token。
let createToken = jwt.sign({
  data: 'jiamideshuju'
}, 'lingpai', { expiresIn: 3 });

console.log('生成的token', createToken)

setTimeout(()=>{
  // 查看token是否过期
  var decoded = jwt.verify(createToken, 'lingpai')
  console.log('4s后token是否过期', decoded)
},4000)

封装生成token与验证token是否过期

utils/createTokenCheck.js文件

// 引入 jsonwebtoken
let jwt = require('jsonwebtoken');

let lingpai = 'weislingpai'
const createTokenCheck = {
  // 生成的token。并设置过期时间
  getToken(jiamiData,expiresIn=3){
    return jwt.sign({
      data: jiamiData
    }, lingpai, { expiresIn: expiresIn })
  },
  // 检查token是否过期
  verify(token){
    try {
     return jwt.verify(token, lingpai)
    } catch (error) {
      // 如果报错返回false.[因为token有可能过期,就会报错]
      console.log('error:', error)
      return false
    }
  }
}
// 暴露出去,其他地方调用就行
module.exports = createTokenCheck


app.js文件调用

const createTokenCheck =require('./utils/createTokenCheck')
let token= createTokenCheck.getToken('zhangsan',2)
console.log('不会过期', token)
setTimeout(() => {
  let data=createTokenCheck.verify(token)
  console.log('过期返回false', data)
}, 3000);

登录验证

前端代码
<template>
  <div>
    <h2>登录页</h2>
    <form action="">
      用户名:<input type="text" v-model="userInfo.user"> <br>
      密  码:<input type="password" v-model="userInfo.password"><br>
      <button @click="handlerLogin">登录</button>
    </form>
  </div>
</template>

<script setup lang="ts">
import {reactive} from 'vue'
import axios from 'axios'
const userInfo = reactive({
  user:'',
  password:''
})
const handlerLogin=()=>{
  axios.post('http://127.0.0.1:3000/login', {
    user:userInfo.user,
    password: userInfo.password,
  }).then(res => {
      console.log(res);
  }).catch(error => {
      console.log(error);
  });
}
</script>


app.js

app.post('/login',  function(req, res) {
  console.log('req', req.body)
  //通过req.body接收传递的参数
  let { user, password } = req.body
  // 我们假设用户是这样就会成功
  if(user==='zhangsan'&& password==='123'){
    // 生成token 过期时间设置为10s
    let token= createTokenCheck.getToken('zhangsan',10)
    // 发送token
    res.send({
      code: 'ok',
      msg:'登录成功',
      token:token
    });
  }else{
    res.send({
      code: 'fail',
      msg: '登录失败',
    });
  }
})

无法加载响应数据: No data found for resource with given identifier

我们现在需要下载 cors
npm i cors
然后在app.js中引入
const cors = require('cors')
// 放置在路由的前面
app.use(cors())

'req.body' as it is undefined.

//放置在路由的前面
app.use(express.json());

前端接口携带token

携带token

<template>
  <div>
    <h1 class="h1">我是test文件</h1>
  </div>
</template>

<script setup lang="ts">
import axios from 'axios'
const handlerLogin=()=>{
  axios.post('http://127.0.0.1:3000/list',{},{
    headers:{
      authorization: localStorage.getItem('token')
    }
  }).then(res => {
    console.log(res)
    console.log(res);
  }).catch(error => {
      console.log(error);
  });
}
handlerLogin()
</script>


aap.js代码
const createTokenCheck =require('./utils/createTokenCheck')
// 处理跨域
const cors = require('cors')
const express = require('express')
const app = express()
app.use(cors())
// 处理  'req.body' as it is undefined.
app.use(express.json());
const port = 3000

app.get('/', (req, res) => res.send('Hello World!'))

app.post('/login',  function(req, res) {
  console.log('req', req.body)
  //通过req.body接收传递的参数
  let { user, password } = req.body
  // 我们假设用户是这样就会成功
  if(user==='zhangsan'&& password==='123'){
    // 生成token 过期时间设置为10s
    let token= createTokenCheck.getToken('zhangsan',10)
    // 发送token
    res.send({
      code: 'ok',
      msg:'登录成功',
      token:token
    });
  }else{
    res.send({
      code: 'fail',
      msg: '登录失败',
    });
  }
})

app.post('/list',  (req, res) =>{
  let getToken = (req.headers &&  req.headers.authorization) || ''
  if(getToken){
    // 检查token是否过期
    if(createTokenCheck.verify(getToken)){
      res.send({
        code: 'ok',
        list: [
          {name:'张三',grade:98, status:'通过考试'},
          {name:'李四',grade:58, status:'未通过考试'},
          {name:'王五',grade:78, status:'通过考试'}
        ]
      });
    }else{
      res.send({
        code: 'fail',
        list: [],
        msg:'token过期'
      });
    }
  }else{
    res.send({
      code: 'fail',
      list: [],
      msg:'请携带token'
    });
  }
})
app.listen(port, () => console.log(`Example app listening on port ${port}!`))