🌗 实现 HTTP 授权
# 需求分析
在 HTTP 协议中的 Authorization 请求 header
会包含服务器用于验证用户代理身份的凭证,通常会在服务器返回 401
(Unauthorized 状态码) 以及 WWW-Authenticate
消息头之后在后续请求中发送此消息头。
axios 库允许在请求配置中配置 auth
属性, auth
是一个对象结构,包含 username
和 password
两个属性。一旦用户在请求的时候配置这两个属性,就会自动往 HTTP 的请求 header
中添加一个 Authorization
属性,它的值为 Basic
加密串( username:password
base64 加密后的结果)。
🌰 使用例子:
axios.post('/more/post', { a: 1 }, { auth: { username: 'Yee', password: '123456' } }).then(res => { console.log(res) })
1
2
3
4
5
6
7
8
9
10
# 代码实现
修改 AxiosRequestConfig
类型定义, src/types/index.ts
:
export interface AxiosRequestConfig {
// ...
auth?: AxiosBasicCredentials
}
export interface AxiosBasicCredentials {
username: string
password: string
}
1
2
3
4
5
6
7
8
9
2
3
4
5
6
7
8
9
修改合并规则,因为 auth
是一个对象格式,它的合并规则应该是 deepMergeStrat
,添加到 stratKeysDeepMerge
:
( src/core/mergeConfig.ts
)
const stratKeysDeepMerge = ['headers', 'auth']
1
然后修改发送请求之前的逻辑( src/core/xhr.ts
):
export default function xhr(config: AxiosRequestConfig): AxiosPromise {
return new Promise((resolve, reject) => {
const {
// ...
auth
} = config
// ...
function configureRequest(): void {
// ...
if (auth) {
headers['Authorization'] = 'Basic' + btoa(auth.username + ':' + auth.password)
}
}
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
# 编写测试 DEMO
examples/server.js
:
router.post('/more/post',function(req,res){
const auth = req.headers.authorization
const [type,credentials] = auth.split(' ')
console.log(atob(credentials))
const [username,password] = atob(credentials).split(':')
if(type === 'Basic' && username === 'sunib' && password === '123456'){
res.json(req.body)
}else{
res.status(401)
res.end('UnAuthorization')
}
})
1
2
3
4
5
6
7
8
9
10
11
12
2
3
4
5
6
7
8
9
10
11
12
需要安装
atob
实现 base64 串的解码。
examples/more/app.ts
:
axios
.post(
'/more/post',
{
a: 1
},
{
auth: {
username: 'simon',
password: '123456'
}
}
)
.then(res => {
console.log(res)
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
编辑 (opens new window)
📢 上次更新: 2022/09/02, 10:18:16