koa+vue+axios,token生成,jwt的使用

提示:koa + vue + axios


前言

不理解具体的token保持登录的原理,所以研究了一下,做下总结

一、jwt

什么是jwt:

写了半天官方解释,感觉不太好理解,表述下自己的理解,如果想看官方下方有地址。
JWT是一个标准,把json格式的数据进行加密进行传输;流程大概如下:
	1、客户端登录,发送用户信息给服务器,服务器验证用户信息成功后,生成一个token,返回给客户端
    2、客户端接收token,存储在本地,之后所有的请求都带上token
    3、客户端发送其他(非注册登录)的请求携带token
    4、服务器接收到请求后,验证token,这里是用jwt的规则对token进行解析,解析token是否过期,解析token中用户的信息
    5、如果token仍在有效期内,并且通过服务器自定义的secret  key与加密方式,可以解析出用户信息,服务器执行接收到的请求
    优点:不用每次都操作数据库验证用户信息
    缺点:token是存储在客户端的,在传输过程中,可能被获取,存再风险,传输中用https,服务器自定义的secret key不能泄露,

token示例展示:

//token结构组成
header.payload.signature
//示例
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9   //header
.eyJ1c2VyRGF0YSI6eyJ1c2VyTmFtZSI6ImFkbWluIiwicGFzc3dvcmQiOiIxMjM0NTYifSwiaWF0IjoxNjY3OTg0NzI0LCJleHAiOjE2Njc5ODgzMjR9   //Payload
.LAPHZoqFDfVUijJRv7CZVrEF32LVOktUzPqFoOWfPa8  //Signature

二、token的生成和验证

一、 前端代码

1、新建项目test

//进入test项目后执行
vue init webpack test
npm install js-cookie
npm install axios
//启动项目
npm run dev

2、HellowWorld.vue

<template>
  <div class="hello">
    <div v-if="noLogin" class="loginBox">
      <p class="ipt"><input v-model="userName" type="text"></p>
      <p class=""><input v-model="password" type="password"></p>
      <button @click="goLogin">登录</button>
    </div>
    <div v-else class="testBox">
      <button @click="goTest">发送带token的请求</button>
    </div>
  </div>
</template>

<script>
import requestApi from "@/api/request";
import Cookies from 'js-cookie'
export default {
  name: "HelloWorld",
  data() {
    return {
      noLogin: true,
      userName: "",
      password: "",
    };
  },
  methods: {
    goLogin() {
      requestApi.login({userName:this.userName,password:this.password}).then((res) => {
        Cookies.set('token',res.data.token);
        this.noLogin = false;
      });
    },
    goTest() {
       requestApi.test({test:'执行test'}).then((res) => {
        console.log(res)
      });
    },
  },
};
</script>

3、api/request.js

import axios from 'axios';
import Cookies from 'js-cookie'

const token = Cookies.get('token');

const request = axios.create({
  baseURL: 'http://localhost:3000',
  withCredentials: true,
  headers: {'Content-Type': 'application/json'},
});
if(token){
  request.defaults.headers.common['Authorization'] = 'Bearer '+ token;
}

request.interceptors.request.use(
  config => {
    return config;
  }, err => {
    return Promise.reject(err);
  });

request.interceptors.response.use((data) => {
  return data.data
}, (err) => {
  return err
});

const resquestApi = {
  login(params) {
    return request.post('/api/login/login', params);
  },
  test(params){
    return request.post('/api/login/test', params);
  }
}
export default resquestApi;
二、 后端代码

1、新建项目testkoa

//新建文件夹testkoa
//进入testkoa项目后执行
npm init -y
npm install koa koa-bodyparser koa-static koa-session-minimal koa-cors jsonwebtoken koa-router
node main.js

1、main.js

const Koa = require('koa');
const bodyParser = require('koa-bodyparser');
const staticServe = require('koa-static');
const session = require('koa-session-minimal');
const cors = require('koa-cors');
//token
const jwt = require('jsonwebtoken');
const TOKEN_SECRET_KEY = '加密key';
//router
const router = require('koa-router')();

const app = new Koa();
app.use(cors({
    origin: 'http://localhost:8080',
    allowMethods: ['GET', 'POST', 'PUT', 'DELETE', 'OPTIONS'],
    allowHeaders: ['Content-Type', 'Authorization', 'Accept'],
    credentials: true
}));

app.use(session({
    key: 'sesson_id',
    cookie: {
        maxAge: 1000 * 60 * 1, // cookie有效时长
        path: '/', // 写cookie所在的路径
        domain: 'localhost', // 写cookie所在的域名-------这里不加也可以
        httpOnly: true, // 是否只用于http请求中获取
        overwrite: false, // 是否允许重写
    }
}))

const sign_token = (userData) => {
    //web传入参数,加密key,过期时间
    return jwt.sign(userData, TOKEN_SECRET_KEY, {
        expiresIn: '1h'
    });
}
const check_token = async (ctx) => {
    if (!ctx.header.authorization || ctx.header.authorization.length < 1) {
        return
    }
    const token = ctx.header.authorization.split('Bearer ')[1];
    //"未登录,请前往登录!"
    if (!token || token.length < 1) return false;
    try {
        // 或者用 //let userData = await jwt.decode(token);
        let userData = await jwt.verify(token, TOKEN_SECRET_KEY);
        return userData;
    } catch (err) {
        //登录过期,请前往登录!
        return false
    }
}

const test = async (ctx) => {
    const result = await check_token(ctx);
    let body = {
        success: false,
        msg: '登录信息验证失败',
    };
    if (result) {
        //执行实际当前接口请求的操作就可以,不需要去数据库验证用户信息
        body = {
            success: false,
            msg: 'test请求成功',
            data:result
        };
    }
    ctx.body = body;
}
const login = (ctx) => {
    let userData = ctx.request.body;
    let reObj = {
        userName: userData.userName
    }
    reObj.token = sign_token({
        userName: userData.userName
    });
    ctx.body = {
        success: true,
        msg: '登录成功!',
        data: reObj
    }
}
//登录
router.post(`/api/login/login`, login);
//测试请求验证token
router.post(`/api/login/test`, test);


app.use(bodyParser());
app.use(staticServe(__dirname + '/public'));
app.use(router.routes());
app.use(router.allowedMethods());
app.listen(3000, () => {
    console.log('localhost:3000');
});

三、页面效果

1、初始化页面,cookie没有任何值
在这里插入图片描述
2、执行login请求,headers无token信息
在这里插入图片描述
执行login请求,payload传参
在这里插入图片描述
执行login请求,返回token信息,存储到cookie
在这里插入图片描述
cookie此时有了token信息
在这里插入图片描述
执行test请求,headers中包含了token的信息
在这里插入图片描述
执行test请求,payload传参
在这里插入图片描述
执行test请求,返回token解析后的json数据
在这里插入图片描述

四、官方解释

jwt官网:

JSON Web Token (JWT) is an open standard (RFC 7519) that defines a compact and self-contained way for securely transmitting information between parties as a JSON object. This information can be verified and trusted because it is digitally signed. JWTs can be signed using a secret (with the HMAC algorithm) or a public/private key pair using RSA or ECDSA.

JSON Web Token(JWT)是一个开放标准(RFC 7519),它定义了一种紧凑且自包含的方式,用于在各方之间以JSON对象的形式安全地传输信息。此信息可以被验证和信任,因为它是经过数字签名的。JWT可以使用秘密(使用HMAC算法)或使用RSA或ECDSA的公钥/私钥对进行签名。

JSON Web Token由3部分组成:
1、Header
2、Payload
3、Signature
类似于下列结构

	xxxxx.yyyyy.zzzzz
	header.payload.signature

1、header
头部通常由两部分组成:令牌类型(JWT)和使用的签名算法(如HMAC SHA256或RSA)

{
  "alg": "HS256",
  "typ": "JWT"
}

2.Payload
令牌的第二部分是有效载荷,其中包含声明。声明是关于实体(通常是用户)和其他数据的声明。索赔有三种类型:注册索赔、公共索赔和私人索赔。

{
  "sub": "1234567890",
  "name": "John Doe",
  "admin": true
}

3.Signature
要创建签名部分,您必须获取编码的头、编码的有效载荷、秘密、头中指定的算法,并对其进行签名。
例如,如果您想使用HMAC SHA256算法,签名将按以下方式创建:

HMACSHA256(
  base64UrlEncode(header) + "." +
  base64UrlEncode(payload),
  secret)

总结

踩坑路漫漫长@~@

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
好的,下面是一个使用 Koa + JSON + JWT + Token 的图书管理系统后端服务器的示例代码。 首先,安装必要的依赖: ```bash npm install koa koa-router koa-bodyparser jsonwebtoken uuid ``` 其koaKoa 框架本身,koa-router 是路由模块,koa-bodyparser 是解析请求体的模块,jsonwebtoken生成和验证 JWT 的模块,uuid 是生成唯一标识符的模块。 然后,创建一个 index.js 文件,输入以下代码: ```javascript const Koa = require('koa'); const Router = require('koa-router'); const bodyParser = require('koa-bodyparser'); const jwt = require('jsonwebtoken'); const uuid = require('uuid'); const app = new Koa(); const router = new Router(); const books = [ { id: '1', name: 'JavaScript 高级程序设计', author: 'Nicholas C. Zakas' }, { id: '2', name: 'JavaScript DOM 编程艺术', author: 'Jeremy Keith' }, { id: '3', name: 'JavaScript 语言精粹', author: 'Douglas Crockford' }, ]; const secret = 'my-secret'; router.post('/login', async (ctx) => { const { username, password } = ctx.request.body; if (username === 'admin' && password === 'admin123') { const token = jwt.sign({ username }, secret, { expiresIn: '1h' }); ctx.body = { token }; } else { ctx.status = 401; ctx.body = { message: 'Invalid credentials' }; } }); router.get('/books', async (ctx) => { const token = ctx.request.headers.authorization; if (!token) { ctx.status = 401; ctx.body = { message: 'Missing authentication token' }; return; } try { const decoded = jwt.verify(token, secret); ctx.body = { books }; } catch (error) { ctx.status = 401; ctx.body = { message: 'Invalid authentication token' }; } }); router.post('/books', async (ctx) => { const token = ctx.request.headers.authorization; if (!token) { ctx.status = 401; ctx.body = { message: 'Missing authentication token' }; return; } try { const decoded = jwt.verify(token, secret); const { name, author } = ctx.request.body; const id = uuid.v4(); books.push({ id, name, author }); ctx.body = { id }; } catch (error) { ctx.status = 401; ctx.body = { message: 'Invalid authentication token' }; } }); app.use(bodyParser()); app.use(router.routes()); app.use(router.allowedMethods()); app.listen(3000, () => console.log('Server is running on http://localhost:3000')); ``` 该代码实现了以下功能: 1. 登录接口:POST /login,接受用户名和密码,验证成功后返回一个 JWT。 2. 获取图书列表接口:GET /books,需要在请求头带上 JWT,验证成功后返回图书列表。 3. 添加图书接口:POST /books,需要在请求头带上 JWT,验证成功后添加一本图书,并返回该图书的 ID。 这个示例代码是一个比较简单的图书管理系统后端服务器,可以根据实际需求进行修改和完善。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值