机制本身
Basic 认证由 RFC 7617 定义,是 HTTP 中最简单的认证方案。客户端用冒号把用户名和密码连接起来,对结果做 base64 编码,然后放进请求头:
Authorization: Basic YWxpY2U6czNjcjN0
当服务器需要凭据时,会返回 401 Unauthorized 并带上 WWW-Authenticate: Basic realm="...",浏览器随即弹出原生登录框。整个过程没有握手、没有随机数、没有有效期 —— 每个请求都携带同一个请求头。
base64 不是加密
这一点必须刻进脑子里。base64 是一种可逆的传输编码,既没有密钥也没有秘密可言。任何看到这个请求头的人都能瞬间解出内容,本页的解码器做的正是这件事。因此 Basic 认证本身提供的机密性是零,只能在 HTTPS 之上使用,由 TLS 保护整个请求。跑在明文 HTTP 上,它等价于直接发送明文密码。
冒号规则
用户名中不能包含冒号,因为第一个冒号就是分隔符。密码里想有多少冒号都可以 —— 解码器只在第一个冒号处切分,其余全部算作密码。如果你的用户名确实需要冒号,那么 Basic 认证不可用,得换方案。
字符编码
最初的规范对 ASCII 之外的字符语焉不详,历史上导致非 ASCII 密码在客户端与服务端之间频繁出错。RFC 7617 增加了 charset="UTF-8" 参数,让服务器可以声明自己的预期;实践中现代技术栈一律使用 UTF-8。本工具在 base64 之前先编码为 UTF-8 字节,与当前浏览器行为一致。
它仍然合适的场景
Basic 认证在这些场合依然合理:内网中的机器对机器调用;用 nginx 或 Apache 快速给预发布环境加一道门;需要简单凭据的 CI 任务;以及作为 API Key 的载体 —— 把 key 放进用户名字段,密码留空或填一个占位符如 x。多家支付和邮件 API 用的正是这种模式。
它不适合公开站点的终端用户登录:没有登出机制,浏览器会在会话期内缓存凭据,弹框无法定制样式,也没法加多因素认证或按会话限流。这类场景应改用令牌或会话方案。
实践中的注意事项
写在 URL 里的凭据 —— user:pass@example.com —— 已被废弃,多数浏览器会拦截或剥离,因为它会泄漏进历史记录、日志和 referrer 头。给 curl 传 -u user:pass 同样会把密码写进 shell 历史和进程列表,机器上的其他用户能直接看到;更好的做法是只写 -u user 让 curl 提示输入,或者从环境变量读取。