jwt的学习

JWT

什么是JWT

jwt:json web token 是目前来说,最流行的跨域认证解决方案。

身份认证

验证身份,鉴定权限。

  1. 服务端渲染推荐使用session认证机制
  2. 前后端分离推荐使用JWT认证机制

工作原理和流程

  1. 用户的信息通过Token字符串的形式,保存在客户端浏览器中。
  2. 服务器通过还原Token字符串的形式来认证用户的身份。

image-20220120095020287
JWT的组成部分

  1. 分为三部分组成:Header(头部),Payload(载荷),Signature(签名)
  2. Token是字符串,三者之间使用英文的.分割。【header.payload.signature】
  3. Payload里面才是真正的用户信息。它是用户信息经过加密之后生成的字符串。
  4. Header和Signature 是安全相关的部分,只是为了保证token的安全性。
    使用步骤

安装相关包

npm i jsonwebtoken  express-jwt
  • jsonwebtoken:用于生成Token字符串
  • express-jwt:用于将jwt字符串还原为JSON对象的。

导入相关包

在app.js中导入相关包

const jwt = require("jsonwebtoken");
const expressJwt = require("express-jwt");

定义秘钥

为了保证JWT字符串的安全性,我们需要定义一个用于加密和解密的secret秘钥(发电报的时候的密码本)

  • 生成token的时候,需要使用secret对用户信息进行加密
  • 接收到请求后,需要将接受的token用secret解密为用户信息对象。

登录成功后生成JWT字符串

调用jsonwebtoken 包提供的sign函数,来将用户的信息加密为JWT字符串。

实例 创建node项目
引入相应的包结构
app.js

const express = require('express')
const jwt = require("jsonwebtoken")
const expressJwt = require("express-jwt")
const bodyParser = require('body-parser')
const app = express()
const port = 3000

//解析post参数
app.use(bodyParser.urlencoded({extended:false}));
//定义密钥
const secretkey = "qwer";

// expressJwt中间件 将jwt字符串还原为json对象
//secret 密钥
//algorithms 解密加密的算法 默认值
//这一句话加上后,所有的请求都需要添加Authorization字段,并将token传递过去。
//unless表示忽略哪些接口,不需要token验证就可以访问。
//path接受一个数组,数组中是不需要验证的接口
app.use(expressJwt({secret:secretkey,algorithms:['HS256']}).unless({path:["/login"]}));

//首页

app.get('/', (req, res) => {
    //使用req.user 获取用户信息
    console.log(req.user);

    res.send(`welcome,${req.user.username}`)
    });

//登录接口
app.post("/login",(req,res)=>{
    //获取用户名传入的用户名和密码
    const {username,password} = req.body;
    //判断是否成功
    if(username !=="admin" || password !=="000000"){
        res.send({
            status:"400",
            message:"用户名或密码错误"
        })
    }
    //登录成功 生成Token字符串
    //sigin第一个参数: 用户的信息对象
    //sign 第二个参数: 密钥
    //sign 第三个参数 配置对象 比方可以配置有效期

    const token = jwt.sign({username},secretkey,{expiresIn:"3h"});
    res.send({
        status:"200",
        message:"登录成功",
        token   //将token返回给客户端
    })

})
//自定义错误处理中间件
app.use((err,req,res,next)=>{
    //token出错了
    if(err.name == "UnauthorizedError"){
        res.send({
            statue:"401",
            message:"无效的token"
        })
    }
    res.send({
        status:"500",
        message:"未知的错误发送了"
    })
})
app.listen(port, () => console.log(`Example app listening on port ${port}!`))

测试接口
在这里插入图片描述
传输参数
在这里插入图片描述
index.html

<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Document</title>
  <link href="https://cdn.bootcdn.net/ajax/libs/twitter-bootstrap/3.4.1/css/bootstrap.min.css" rel="stylesheet">

  <style>
    .container {
      width: 600px;
    }

    .btn-primary {
      width: 100%;
    }
  </style>
</head>

<body>
  <div class="container">
    <form>
      <div class="form-group">
        <label for="username">用户名:</label>
        <input type="text" class="form-control" id="username" placeholder="请输入用户名">
      </div>
      <div class="form-group">
        <label for="password">密码:</label>
        <input type="password" class="form-control" id="password" placeholder="请输入密码">
      </div>
      <button id="login" type="button" class="btn btn-primary">登录</button>
    </form>
    <button id="getInfo">获取用户信息</button>
  </div>
  <script src="https://cdn.bootcdn.net/ajax/libs/axios/0.24.0/axios.min.js"></script>
  <script>
    axios.defaults.baseURL = "http://localhost:3000"
    //当用户点击登录时,发起请求,将用户名与密码传递到后端服务器,由服务器验证后,生成token,返回前端。前端保存到本地中。
    let loginBtn = document.getElementById("login");
    loginBtn.onclick = function (event) {
      //阻止表单的默认提交  或者将登录按钮的类型从submit改为button
      // event.preventDefault();
      //获取用户名
      let username = document.getElementById("username").value;
      //获取密码
      let password = document.getElementById("password").value;
      //向后端发起请求
      axios.post("/login", { username, password }).then(resp => {
        let { data } = resp;
        //说明成功了
        if (data.status == "200") {
          //将token保存到本地。
          localStorage.setItem("token", data.token);
        }
      })
    }
    document.getElementById("getInfo").onclick = function () { 
      axios.get("/getInfo",{
        //设置请求头
        headers:{
          "Authorization":"Bearer "+localStorage.getItem("token")
        }
      }).then(resp=>{
        let {data} = resp;
        console.log(data);
      })
     }
  </script>
</body>

</html>
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值