目录

🌗 实现 HTTP 授权

# 需求分析

在 HTTP 协议中的 Authorization 请求 header 会包含服务器用于验证用户代理身份的凭证,通常会在服务器返回 401 (Unauthorized 状态码) 以及 WWW-Authenticate 消息头之后在后续请求中发送此消息头。

axios 库允许在请求配置中配置 auth 属性, auth 是一个对象结构,包含 usernamepassword 两个属性。一旦用户在请求的时候配置这两个属性,就会自动往 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

修改合并规则,因为 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

# 编写测试 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

需要安装 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
📢 上次更新: 2022/09/02, 10:18:16