token的理解和代码,token是什么?

面试场景:

以前有个学生去面试,公司问他,如果你们公司的接口文档被你的亲戚看到了,会怎么样?会导致什么问题,为了防止这个问题,需要用什么来解决?这个根据学生回忆的写的。

学生当场懵逼。我的亲戚……,我的亲戚看不懂啊……%¥#?~%¥#?~………………,我的亲戚也不懂程序啊%¥#?~%¥#?~%¥#?~………………

其实,面试官想问的意思是,如果一个公司的接口文档被别人(懂程序,懂前端的人)看见,他如果写个代码发送请求,是不是可以把数据库中的数据拿到,如何防止这种情况。

这个其实就是一个身份,鉴权的问题。现在前后端分离开发后,一般都用token解决。

本文章后端使用node+mySQL,和 JWT(JSON WEB TOKEN)。

一、token的思路

1、客户端使用用户名和密码请求登录接口(前端做)

2、服务端收到请求,去验证用户名与密码 (后端做)

3、验证成功后,服务端会签发(产生)一个 Token(加了密的字符串),再把这个 Token 发送给客户端(后端做)

4、客户端收到 Token 以后可以把它存储起来,比如放在 Cookie 里或者 Local Storage (sessionStorage)里(前端)

5、客户端每次向服务端请求资源的时候需要带着服务端签发的 Token(前端)

6、服务端收到请求,然后去验证客户端请求里面带着的 Token,如果验证成功,就向客户端返回请求的数据

二、代码:

1、登录时,产生token。
1)、前端代码:

输入用户名和密码,发送请求。登录成功后,把后端响应的token保存起来。

<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>登录页面</title>
</head>
<body><div><h1>登录页面</h1><p>手机号:*<input type="text" id="userphone"></p><p>密码:<input type="password" id="userpass"></p><p><input type="button" value="登录" id="btnLogin"><span id="errMsg"></span></p></div>
</body>
</html>
<script src="./js/jquery.js"></script>
<script src="./js/ajaxTools.js"></script>//这个是自己封装ajax库
<script src="./js/cookieTools.js"></script>//这个是自己封装的cookie库。
<script>
​
function loginCheck(){// 1、非空判断
​// 2、登录的前后端交互(调用的自己封装的ajax库的函数)ajaxUsePromise02({url:"http://10.12.156.16:9000/login",method:"post",data:`loginname=${$("#userphone").val()}&password=${$("#userpass").val()}`}).then(res=>{if(res.code=="200"){//保存用户名(调用的自己封装的cookie库的函数)saveCookie("userphone",$("#userphone").val(),7);//保存tokensessionStorage.setItem("token",res.data.token);location.href="index.html";}else{$("#errMsg").html("亲,账户号或者密码不对").css({color:"red"});}})
}
​
window.onload = function(){$("#btnLogin").on("click",loginCheck)// document.getElementById("btnLogin").onclick = loginCheck;
}
​
</script>

2)、后端代码:

接收前端传来的用户名和密码。去数据库中验证,验证通过后,产生token,响应给前端。

var express = require("express");
var router = express.Router();
var mysql = require("mysql");
const jwt = require("jsonwebtoken");
​
router.post("/", function (req, res, next) {// 1、接收前端的数据let loginname = req.body.loginname;let password = req.body.password;
​// 2、后端逻辑//  1)、连接数据库var connection = mysql.createConnection({host: "localhost", //主机名user: "root",password: "root",database: "db2308", //库名});
​connection.connect();
​// 2)、执行sql语句let sqlStr = `select * from users where tel='${loginname}' and password='${password}'`;connection.query(sqlStr, function (error, results, fields) {if (error) {res.json({code: "0",msg: "登录失败,连接数据库出错!",});return;}// 3、响应if (results.length == 1) {//产生tokenlet token = jwt.sign({username:loginname,userpass:password}, "who are you?");res.json({code: "200",msg: "登录成功!",data:{loginname:loginname,password:password,token:token//把token响应给前端}})}else{res.json({code: "10011",msg: "登录失败,用户名或者密码不对!",})}});// 3)、关闭数据库connection.end();
});
​
module.exports = router;
​

2、再次发送请求时,携带token
1)、前端代码:

token一般都携带在请求头里。

 // 发送请求,从后端获取商品数据
ajaxUsePromise02({url: `${baseurl}/getGoodslist`,data: data,headers: {token: sessionStorage.getItem("token");// 把token携带在头部}
})

2)、后端代码:

先从请求头里拿到token。然后,验证token是否正确,如果正确,才给前端响应数据。

var express = require("express");
const connection = require("../db/conn");
var router = express.Router();
​
//专门定义一个验证token的函数。
const tokenVerify= function (req, res, success, fail) {// 还需要拿tokenlet token = req.query.token;console.log("token", token);
​try {//这句话是验证token的。let decoded = jwt.verify(token,  "who are you?");console.log("decoded", decoded);
​//  1)、连接数据库var connection = mysql.createConnection({host: "localhost", //主机名user: "root",password: "root",database: "db2308", //库名port: 3306,});connection.connect();
​// 2)、执行sql语句let sqlStr = `select * from users where tel='${decoded.username}' and password='${decoded.userpass}'`;console.log("sqlStr", sqlStr);connection.query(sqlStr, function (error, results, fields) {if (error) {// throw error;console.log("数据库出错了", error);}console.log("执行成功", results);// 3、响应if (results.length == 1) {success();} else {fail();}});// 3)、关闭数据库connection.end();} catch (error) {res.json({code: "-1",msg: "token无效",});}
};
​
​
// 获取所有的商品数据
router.get("/", function (req, res, next) {// 1、接收前端的数据let goodsname = req.query.goodsname;let goodsid = req.query.goodsid;
​//2、验证token,如果成功获取数据。tokenVerify(req,res,function () {// 2、后端逻辑let sqlstr = "select * from goods where 1=1 ";if (goodsid != undefined) {sqlstr += ` and goodsid='${goodsid}'`;}
​if (goodsname != undefined) {sqlstr += ` and goodsname='${goodsname}'`;}
​console.log("sqlstr", sqlstr);
​// res.setHeader( "access-control-allow-origin","*");
​connection.query(sqlstr, function (error, results, fields) {if (error) {// 3、响应res.json({code: "0",msg: "数据库服务器出问题",});} else {console.log("获取到了商品列表数据");// 3、响应res.json({code: "200",data: results,});}});},function () {res.json({code: "-1",msg: "token不对",});});
});
​
module.exports = router;
 

三、JWT(JSON WEB TOKEN)的两个函数

jsonwebtoken的安装引入

let jwt = require('jsonwebtoken')

生成签名(token)

let token = jwt.sign(payload, secretOrPrivateKey, [options, callback])

[payload]  使用用户输入的信息(如:用户名),加密的原始字符串

[secretOrPrivateKey]  加密规则,字符串,或者私钥path模块,其实就是一串字符串(越乱越好)

[options]  可选配置项 ,如:expiresIn表示 过期时间(单位是秒)

[callback]  成功回调, 可选 返回制作后的token,也可同步返回;如果写了该回调函数就用的回调函数的异步操作,如果不写,那么同步返回

校验token

jwt.verify(token, secretOrPublicKey, [options, callback])

[token]  制作后的token

[secretOrPublicKey]  解密规则,字符串,或者公钥

[callback:]  回调 err 错误信息 decode 成功后的信息

[options]  expiresIn 过期时间

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/693891.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

小程序--loading和toast

一、loading wx.showLoading({})显示loading提示框。wx.hideLoading({})隐藏loading提示框。 title&#xff1a;文字提示内容 mask&#xff1a;是否显示透明蒙层&#xff0c;防止触摸穿透。 更多属性参考showLoading官方文档。 wx.showLoading({title: 加载中...,mask: true }…

力扣面试150 验证回文串 双指针 Character API

Problem: 125. 验证回文串 文章目录 思路复杂度Code 思路 &#x1f468;‍&#x1f3eb; 参考题解 Character.isLetterorDigit(char c)&#xff1a;判读字符 c 是否是字母或者数字 Character.toLowerCase(char c)&#xff1a;将字符 c 转换为小写字母 复杂度 时间复杂度: …

docker (八)-dockerfile制作镜像

一 dockerfile dockerfile通常包含以下几个常用命令&#xff1a; FROM ubuntu:18.04 WORKDIR /app COPY . . RUN make . CMD python app.py EXPOSE 80 FROM 打包使用的基础镜像WORKDIR 相当于cd命令&#xff0c;进入工作目录COPY 将宿主机的文件复制到容器内RUN 打包时执…

十、计算机视觉-腐蚀操作

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 文章目录 一、什么是腐蚀二、如何实现腐蚀三、腐蚀的原理 一、什么是腐蚀 在我们生活中常会见到腐蚀&#xff0c;比如金属表面受到氧化或其他化学物质的侵蚀&#xff0c;导致…

java----js常用的api

java----js常用的api 时间函数获取当前时间: DateUtil.today()时间偏移字符换时间格式化 map.computeIfAbsent添加list 时间函数 获取当前时间: DateUtil.today() String todayDateUtil.today()String today “2024-02-01”; 时间偏移 往前30天 DateTime parseDateUtil.o…

观察者模式和发布订阅模式的区别

从下图中可以看出&#xff0c;观察者模式中观察者和目标直接进行交互&#xff0c;而发布订阅模式中统一由调度中心进行处理&#xff0c;订阅者和发布者互不干扰。这样一方面实现了解耦&#xff0c;还有就是可以实现更细粒度的一些控制。比如发布者发布了很多消息&#xff0c;但…

Project_Euler-06 题解

Project_Euler-06 题解 题目描述 两个公式 等差数列求和公式 i i i项&#xff1a; a i a_{i} ai​ 项数&#xff1a; n n n 公差&#xff1a; d d d 和&#xff1a; S n S_{n} Sn​ a n a 1 ( n − 1 ) d S n n ( a 1 a n ) 2 a_{n} a_{1} (n - 1)d\\ S_{n} \frac{n(a_…

深究 DevOps 与平台工程的区别

今天&#xff0c;我们将讨论平台工程和 DevOps 的关系。尽管这两个概念有一些共同点&#xff0c;但它们仍然是截然不同的&#xff0c;我们将具体了解它们之间的区别。本文旨在解释当代软件工程中的这两个基本概念。通过实际案例&#xff0c;我们将分别说明这两个方法如何塑造了…

MySQL 的存储引擎(基本介绍)

文章目录 前言MySQL 的存储引擎介绍存储引擎是什么&#xff1f;存储引擎的特性? Innodb 与 Mylsam 的区别行级锁与表级锁是否支持事务是否支持恢复数据是否支持外键是否支持 MVCC 总结 前言 好文章不要错过&#xff0c;前两天跟大家分享的文章 1.MySQL的基础架构 2.SQL语句的…

leetcode刷题电话号码的字母组合(人工智能解答版本)

题目描述 解题思路 一开始想用暴力破解的方法来进行解题&#xff0c;就是循环。但是想到随着数字的增多&#xff0c;循环行不通。想到最近使用的一个人工智能助手&#xff0c;于是我把题目发送给了它&#xff0c;直接给出了递归的解决方法。递归分为两个条件&#xff0c;一个就…

【k近邻】 K-Nearest Neighbors算法原理及流程

【k近邻】 K-Nearest Neighbors算法原理及流程 【k近邻】 K-Nearest Neighbors算法距离度量选择与数据维度归一化 k近邻算法&#xff08;K-Nearest Neighbors&#xff0c;简称KNN&#xff09;是一种常用的监督学习算法&#xff0c;可以用于分类和回归问题。在OpenCV中&#xff…

【关于python变量类型学习笔记】

python的变量类型 在创建变量时会在内存中开辟一个空间&#xff0c;变量是存储在内存中的值。 根据变量的数据类型&#xff0c;解释器会分配指定内存&#xff0c;并决定什么数据可以被存储在内存中。 变量可以指定不同的数据类型&#xff0c;这些变量可以存储整数&#xff0c;…

C++基础学习

string char转string vector转string 截取字符串 字符串反转 string转int 正则匹配

Nginx 反向代理配置

Nginx就不废话了&#xff0c;web服务器。 最近在备案一个域名&#xff0c;想要备案&#xff0c;部署一个服务器&#xff0c;平常很少自己配置Nginx&#xff0c;今天记录下。 1、反向代理 正向代理 指 客户端通过代理访问后端服务 反向代理 指 服务器推出一个客户&#xff0…

环信IM Android端实现华为推送详细步骤

首先我们要参照华为的官网去完成 &#xff0c;以下两个配置都是华为文档为我们提供的 1.https://developer.huawei.com/consumer/cn/doc/HMSCore-Guides/android-config-agc-0000001050170137#section19884105518498 2.https://developer.huawei.com/consumer/cn/doc/HMSCore…

#gStore-weekly | gMaster功能详解之数据库管理

gMaster提供了数据库管理功能。该功能可以对集群中的数据库进行集中管理&#xff0c;可以查看各个数据库详细信息。能够方便的对数据库进行新建、构建、导出、备份、还原、删除操作。 登录gMaster&#xff0c;点击左侧菜单【数据库】下的【数据库管理】&#xff0c;进入数据库…

【开源】JAVA+Vue.js实现高校学生管理系统

目录 一、摘要1.1 项目介绍1.2 项目录屏 二、功能模块2.1 学生管理模块2.2 学院课程模块2.3 学生选课模块2.4 成绩管理模块 三、系统设计3.1 用例设计3.2 数据库设计3.2.1 学生表3.2.2 学院课程表3.2.3 学生选课表3.2.4 学生成绩表 四、系统展示五、核心代码5.1 查询课程5.2 新…

动态获取 微信小程序appid / 自定义启动命令

官网&#xff1a;https://uniapp.dcloud.net.cn/collocation/package.html#%E7%94%A8%E6%B3%95 小程序开发完成之后需要一套代码多个小程序使用&#xff0c;每次都需要在manifest.json文件中手动修改&#xff0c;大大增加了开发的复杂度。 官网&#xff1a;https://uniapp.dcl…

使用sass开发web-components组件

思路&#xff1a;借助chokidar监听变化&#xff0c;将scss编译成css后插入 同时执行chokidar监听和webpack server "start": "npm run watch:css & webpack serve","watch:css" : "node chokidarStyles.js",// chokidarStyles.js …

如何解决 SQL 深层分页问题?

我们可以通过减少回表次数来优化。一般有标签记录法和延迟关联法。 标签记录法 就是标记一下上次查询到哪一条了&#xff0c;下次再来查的时候&#xff0c;从该条开始往下扫描。就好像看书一样&#xff0c;上次看到哪里了&#xff0c;你就折叠一下或者夹个书签&#xff0c;下…