【前端45_前后端交互】jwt 授权和鉴权、请求工具:Axios、拦截器、简版 Axios、fetch
文章目录前后端交互jwt (JSON web token)简介知识点补充实现方式签发 Token鉴权网络拦截提出问题前后端交互jwt (JSON web token)简介判断你是否有权限和服务器进行交互,相当于一个门禁吧,过程如下知识点补充token:服务端登录成功后进行签发哈希:对复杂的数据进行摘要,10G 的内容,如果改了1kb ,那么它的哈希值也会改变的实现方式流程:我们以登录过程为例子,登
文章目录
前后端交互
jwt (JSON web token)
简介
判断你是否有权限和服务器进行交互,相当于一个门禁吧,过程如下
知识点补充
token
:服务端登录成功后进行签发
哈希:对复杂的数据进行摘要,10G
的内容,如果改了1kb
,那么它的哈希值也会改变的
实现方式
流程:我们以登录过程为例子,登录成功后签发 token
,访问接口时携带 token
签发 Token
可以通过 jsonwebtoken
这个模块去签发 token
,参考 npm 上的模块说明,也可以参考 https://jwt.io/ 查看 token 的信息
签发的过程如下
const jwt = require('jsonwebtoken') // 签发 token 的模块
let token = jwt.sign(
{
name: 'some value',
}, // token 中携带的一些参数,你可以自己写,用 base64 加密的
'mytoken', // 秘钥名称,等会用来鉴权时会用到
{ expiresIn: '2h' } // 时效性,一般都是 2 个小时
)
后端签发好 token
后,发送给前端,前端需要保存好token
,可以放到cookie
或者 localStorage
里(推荐放到localStorage
)
鉴权
当前端去访问后台接口时,需要在请求头中带上你的 token
,注意要声明一下 Bearer
// 前端
function checkApi() {
let xhr = new XMLHttpRequest()
// 需要把 token 放到头部带回服务端;
xhr.open('get', '/checkApi', true)
if (localStorage.getItem('token')) {
xhr.setRequestHeader(
'Authorization',
'Bearer ' + localStorage.getItem('token')
// 如果后端是通过 jwt,这边就需要声明一下 Bearer!!!!
)
}
xhr.onload = function () {
// console.log(JSON.parse(xhr.responseText));
let res = JSON.parse(xhr.responseText)
console.log(res)
// 存token;
}
xhr.send()
}
携带好头信息后,后端接口可以这样校验,首先要引入 koajwt
这个模块,然后再写接口时,第二个参数写秘钥的名称:koajwt({ secret: 'secretKey' })
,举例子的话就是以下这样
const koajwt = require('koa-jwt') // 鉴权
// 这边会自动鉴权
router.get('/checkApi', koajwt({ secret: 'mytoken' }), (ctx) => {
ctx.body = {
test: 'value..',
}
})```
图片展示如下:
同源情况下,如果没有权限的话,会报 401
的权限错误,返回 Authentication Error
的报错信息
非同源去检验权限的话报如下的错误,这里不是很明白,为什么 token
错了会报这个错误呢?
成功的话就是正常的接口返回了
至此简单的 jwt
就结束了
请求工具
这里介绍几种方法,axios
以及 fetch
,axios
比较常用
Axios
基础用法
axios
有两种常用的使用方法
第一种
axios({
method: 'post',
url: 'http://localhost:4000/checkUser',
data: {
username: '张三',
password: '123',
},
headers: {},
}).then((res) => {
console.log(res)
if (res.data.token) {
localStorage.setItem('token', res.data.token)
}
})
第二种
axios
.post('http://localhost:4000/checkApi', data, {
headers: {
Authorization:
'Bearer ' + localStorage.getItem('token'),
},
})
.then((res) => console.log(res))
网络拦截
回到刚才的问题上!
提出问题
如果有很多接口都需要验证 token
,那么我们不能在每个接口里都要写验证的语句,那样的话代码就会冗余
有什么办法统一处理这些呢?
就是用拦截器。
Axios 中的拦截器
在每一个 axios
请求的时候都会走拦截器
axios.interceptors.request.use((config) => {
return config
})
axios.interceptors.response.use((res) => {
return res
})
拦截器可以有多个,比方说下面的例子,我们在关心一下拦截器的顺序:
/**
* 拦截器,所有的 axios 请求都会走这里
**/
// 请求拦截器
axios.interceptors.request.use((config) => {
console.log('请求拦截器1:>>', config)
if (localStorage.getItem('token')) {
// 在拦截器里去配置 token
config.headers.Authorization =
'Bearer ' + localStorage.getItem('token')
}
return config
})
axios.interceptors.request.use((config) => {
console.log('请求拦截器2:>>')
return config
})
axios.interceptors.request.use((config) => {
console.log('请求拦截器3:>>')
return config
})
// 响应拦截器
axios.interceptors.response.use((res) => {
// console.log(config)
console.log('响应拦截器1:>>', res)
return res
})
axios.interceptors.response.use((res) => {
// console.log(config)
console.log('响应拦截器2:>>', res)
return res
})
axios.interceptors.response.use((res) => {
// console.log(config)
console.log('响应拦截器3:>>', res)
return res
})
打印的顺序如下图所示:
根据顺序可以分析出,配置能够被冲掉
简版 Axios
抽离出来了:https://blog.csdn.net/u010263423/article/details/119274544
fetch
- 原生的,基于
Promise
封装的 - 默认是
get
请求。 react native
用的挺多。
简单案例
fetch('/fetchtest', {
method: 'post',
body: 'name=张三&age=10', // 发送的内容写在body里了,相当于 axios 中的 data
headers: {
// 默认的应该是:Content-Type: text/plain;charset=UTF-8
'content-type': 'application/x-www-form-urlencoded',
// 前端设置了这个,后台就会在 request.body 里收到 json 格式的数据
},
// content-type 描述的东西要和 body 对应上!
})
.then((res1) => {
console.log('res1:>>', res1) // 并不是我们想要的结果,而是 response 对象
// return res1.text()
// return res1.clone() // 对当前数据进行 深拷贝
return res1.json() // 返还个 json,在第二个then 里能用到
})
.then((res2) => {
console.log('res2:>>', res2)
})
fetch('/fetchtest', {
method: 'post',
body: JSON.stringify({ name: '张三' }), //这里如果有 'name=张三&age=10'
headers: {
'content-type': 'application/json', // content-type 描述的东西要和 body 对应上!
},
})
也可以实例化一个 headers
对象,然后追加,最后赋值给 headers
即可。
let myHeader = new Headers()
myHeader.append('Content-type', 'application/json')
myHeader.append('myTest', '123')
缺点
- 不能上传文件
- 兼容性,不如
xmlHttpRequest
更多推荐
所有评论(0)