当前位置:网站首页>Nodejs中使用jsonwebtoken(JWT)生成token的场景使用
Nodejs中使用jsonwebtoken(JWT)生成token的场景使用
2020-11-06 22:11:00 【进击的前端】
Ⅰ- 壹 - jsonwebtoken简介
一 为什么需要 token
-
http 无状态
-
session 无法跨服务器
-
cors 跨域以后 cookie 无法使用
在前后分离的项目中,每次请求session都会变化,前端调用后端api接口,因此使用cors = require('cors')
来解决了跨域问题,而跨域对于cookie来说,就是两个不同的网站,因此session会不停的变。
在计算机身份认证中是令牌(临时)的意思,在词法分析中是标记的意思。一般我们所说的的token大多是指用于身份验证的token
我们需要每次都知道当前请求的人是谁,但是又不想每次都让他提交用户名和密码,这时就需要有一个等同于用户名密码也能够标识用户身份的东西,即—token
二 什么是token
token是由三段式加密字符串组成以.
分开例如xxxxxxxxxxxxxxxxxxxxx.yyyyyyyyyyyyyyyyyyyyyyyy.zzzzzzzzzzzzz
-
第一段: 头, 签证: 安全信息验证, 你的口令, 进行不可逆加密*
-
第二段: 你要保存的信息: basa64 加密后截取内容,
-
第三段: 额外信息: 不可逆加密
第一段和第三段不可逆加密 哈希散列,第二段 base64 可逆加密
这一段字符串由后端发给前端,再登陆过以后, 生成一个 token 给到前端
Ⅱ - 贰 - jsonwebtoken的使用
一下载使用
npm i jsonwebtoken
||
yarn add jsonwebtoken
在nodejs中直接导入
// 0. 导入
const jwt = require('jsonwebtoken')
二 jsonwebtoken方法
1 生成token:
jwt.sign(你要保存的信息, 口令, 参数)
-
保存的信息
-
口令: 加密口令, 加密的时候混入信息使用, 解密的时候还要这个口令
-
参数: 是一个对象, {}
expiresIn: 过期时间,单位为秒 (‘1d’)*
2 解码token:
jwt.verify(你要解析的 token, 口令, 回调函数)
-
token: 必须是一个指定的 token
-
口令: 必须是加密时候的口令
-
回调函数: 接收结果
const express = require('express')
const jwt = require('jsonwebtoken')
const cors = require('cors')
const router = express.Router()
const app = express()
app.use(cors())
// 准备一个 token 验证的中间件
app.use(function (req, res, next) {
// req.url 表示当前地址
const {
url, headers: {
authorization: token } } = req
// const url = req.url
// const { authorization: token } = req.headers
// const token = req.headers.authorization
// 不需要验证的 请求地址
if (url === '/login' || url === '/banner') return next()
// 来到这里表示需要 token 验证
if (!token) return res.send({
message: '请携带 token 请求', code: 0 })
jwt.verify(token, 'Josiah', (err, data) => {
if (err && err.message === 'invalid token') return res.send({
message: '无效 token', code: 0 })
if (err && err.message === 'jwt expired') return res.send({
message: 'token 失效', code: 0 })
next()
})
})
router.get('/login', (req, res) => {
// 默认登录成功
const userInfo = {
username: 'XXX',
age: 18
}
// 生成一个 token 返回给前端
const token = jwt.sign(userInfo, 'Josiah, {
expiresIn: 60 })
res.send({
message: '登录成功', code: 1, token })
})
// 第二次测试
router.get('/cartInfo', (req, res) => {
res.send({
message: '获取购物车数据成功', code: 1 })
})
router.get('/pay', (req, res) => {
res.send({
message: '支付成功', code: 1 })
})
// 第一次测试
// router.get('/cartInfo', (req, res) => {
// 你想要购物车数据
// 那么你必须登录以后
// 验证 token 是不是正确
// req, 是本次请求的信息
// req.headers 就是本次的请求头
// const token = req.headers.authorization
// // 1. 有没有
// if (!token) return res.send({ message: '该请求需要 token', code: 0 })
// // 2. 对不对
// jwt.verify(token, 'guoxiang', (err, data) => {
// if (err && err.message === 'invalid token') return res.send({ message: '无效 token', code: 0 })
// if (err && err.message === 'jwt expired') return res.send({ message: 'token 失效', code: 0 })
// res.send({ message: '获取购物车数据成功', code: 1 })
// })
// })
router.get('/banner', (req, res) => {
// 你需要轮播图信息
// 不需要登录验证
res.send({
message: '轮播图数据获取成功', code: 1, list: [ {
}, {
} ] })
})
app.use(router)
app.listen(8080, () => console.log('running at 8080'))
三 测试使用
token的生成和解码
// 0. 导入
const jwt = require('jsonwebtoken')
// 准备一个信息
const userInfo = {
_id: '2131245655',
username: '小星星',
age: 18,
gender: '男'
}
// 1. 生成一个 token
const res = jwt.sign(userInfo, 'key', {
expiresIn: 20 })
console.log(res)
//res会生成一下内容
// eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.
// eyJfaWQiOiIyMTMxMjQ1NjU1IiwidXNlcm5hbWUiOiLpg63nv5QiLCJhZ2UiOjE4LCJnZW5kZXIiOiLnlLciLCJpYXQiOjE1OTkxOTk2MDYsImV4cCI6MTU5OTE5OTYxNn0.
// Cg-PxkAzTnCUF9xja1O9gcOmRzaRsw4TlFM2nCZenAw
// 2. 解码
jwt.verify(res, 'key', (err, data) => {
console.log('第一次 1.5s')
if (err) return console.log(err)
console.log(data)
})
Ⅲ - 叁 - 第三方插件express-jwt
- 是一个express框架和jwt结合的第三方中间件
- 作用:验证token
- 用这个插件需要和sonwebtoken一起使用
注意:
- 如果你要使用 express-jwt你必须有一个全局错误中间件
- 正常的 token 返回给前端,需要写成 Bearer token
以下案例用到的插件:
express、jsonwebtoken、express-jwt、cors
app.js
const express = require('express')
const jwt = require('jsonwebtoken')
const expressJWT = require('express-jwt')
const cors = require('cors')
const router = expryicisess.Router()
const app = express()
app.use(cors());//解决跨域问题
// app.use() 里面放的 expressJWT().unless()
// 注册 token 验证中间件
app.use(expressJWT({
// 解析口令, 需要和加密的时候一致
secret: 'Josiah',
// 加密方式: SHA256 加密方式在 express-jwt 里面叫做 HS256
algorithms: ['HS256']
}).unless({
// 不需要验证 token 的路径标识符
path: ['/login', '/banner']
}))
router.get('/login', (req, res) => {
// 默认登录成功
const userInfo = {
username: '郭翔',
age: 18
}
// 生成一个 token 返回给前端
const token = 'Bearer ' + jwt.sign(userInfo, 'Josiah', {
expiresIn: 60 })
res.send({
message: '登录成功', code: 1, token })
})
app.use(router)
// 错误处理中间件
app.use((err, req, res, next) => {
res.send({
err })
})
app.listen(8080, () => console.log('running at 8080'))
login.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
</head>
<body>
<button>登录</button>
<script>
// 如果你是做后台管理系统, 一般存储在 sessionStorage
// window.sessionStorage.setItem('abc', '100')
// 前端携带 token 我们存储在 请求头 里面携带
// authorization: token
const xhr = new XMLHttpRequest()
const token = window.localStorage.getItem('token')
xhr.open('GET', 'http://localhost:8080/cartInfo')
xhr.onload = function () {
const res = JSON.parse(xhr.responseText)
console.log(res)
}
xhr.setRequestHeader('authorization', token)
xhr.send()
</script>
</body>
</html>
0 - 0 - 知识点:
一 在生成token的时候
需要在生成之前添加 Bearer
后面有个空格
const token = 'Bearer ' + jwt.sign(userInfo, 'guoxiang', { expiresIn: 60 })
二在解析token的时候
- 解析口令, 需要和加密的时候一致
- 加密方式: SHA256 加密方式在 express-jwt 里面叫做 HS256
// app.use() 里面放的 expressJWT().unless()
// 注册 token 验证中间件
app.use(expressJWT({
// 解析口令, 需要和加密的时候一致
secret: 'guoxiang',
// 加密方式: SHA256 加密方式在 express-jwt 里面叫做 HS256
algorithms: ['HS256']
}).unless({
// 不需要验证 token 的路径标识符
path: ['/login', '/banner']
}))
三 在前端获取的时候
- 如果你是做后台管理系统, 一般存储在 sessionStorage
- 前端携带 token 我们存储在 请求头 里面携带,一般使用authorization
xhr.setRequestHeader('authorization', token)
版权声明
本文为[进击的前端]所创,转载请带上原文链接,感谢
https://my.oschina.net/u/4618999/blog/4706905
边栏推荐
- Application insights application insights use application maps to build request link views
- How much disk space does a file of 1 byte actually occupy
- This project allows you to quickly learn about a programming language in a few minutes
- The legality of IPFs / filecoin: protecting personal privacy from disclosure
- 面试官: ShardingSphere 学一下吧
- Those who have worked in China for six years and a million annual salary want to share these four points with you
- 非易失性MRAM存储器应用于各级高速缓存
- Junit测试出现 empty test suite
- Python basic variable type -- list analysis
- Exclusive interview of guests at | 2020 PostgreSQL Asia Conference: Wang Tao
猜你喜欢
【涂鸦物联网足迹】物联网基础介绍篇
消防器材RFID固定资产管理系统
What is the meaning of sector sealing of filecoin mining machine since the main network of filecoin was put online
An article takes you to understand CSS gradient knowledge
Novice guidance and event management system in game development
The isolation level of transaction and its problems
To solve the problem that the data interface is not updated after WPF binding set
How to prepare for the system design interview
Small program introduction to proficient (2): understand the four important files of small program development
C calls SendMessage to refresh the taskbar icon (the icon does not disappear at the end of forcing)
随机推荐
How much disk space does a new empty file take?
CloudQuery V1.2.0 版本发布
2020-08-14:数据任务的执行引擎用的哪些?
小熊派开发板实践:智慧路灯沙箱实验之真实设备接入
2020 database technology conference helps technology upgrade
2020-08-18:介绍下MR过程?
Small program introduction to proficient (2): understand the four important files of small program development
上海巨微专用蓝牙广播芯片
An article will introduce you to HTML tables and their main attributes
ES6 learning notes (4): easy to understand the new grammar of ES6
Application insights application insights use application maps to build request link views
Pn8162 20W PD fast charging chip, PD fast charging charger scheme
Can you do it with only six characters?
To solve the problem that the data interface is not updated after WPF binding set
Junit测试出现 empty test suite
Axios learning notes (2): easy to understand the use of XHR and how to package simple Axios
嘉宾专访|2020 PostgreSQL亚洲大会阿里云数据库专场:曾文旌
迅为-iMX6ULL开发板上配置AP热点
Message queue - Analysis
ES中删除索引的mapping字段时应该考虑的点