Nginx访问认证
生成用户与密码
生成htpasswd
文件需要用到工具htpasswd
,通过以下命令安装:
查看系统:
cat /etc/os-release
在Ubuntu系统上,安装apache2-utils:
apt-get install apache2-utils
在CentOS系统上,安装httpd-tools:
yum install httpd-tools
生成用户:
htpasswd -c /etc/nginx/htpasswd hello
其中hello为用户名, 回车后输入密码及确认密码
配置并重启nginx
nginx
server {
listen 80;
server_name xxx.com;
# [该配置也可放置location中做API授权认证]
# 开启认证并提示信息(实际上chrome和firefox都没提示, 但是这条不能注释掉。具体体现在访问时401的响应头Www-Authenticate中)
auth_basic "Need Login";
# 存储用户名和密码的文件路径
auth_basic_user_file /etc/nginx/htpasswd;
}
systemctl restart nginx
前端流程
- 当配置完后尝试访问,首次会存在响应头,浏览器自动弹出鉴权弹窗,提示输入账号密码:
js
Www-Authenticate: Basic realm="Need login"
- 用户输入账号秘密后,浏览器处理后通过请求头提交到nginx服务器:
- 处理方式为组合字符串
用户名:密码
,并加密成base64. (由于用户名和密码以明文形式(虽然是base64编码,但可以轻易解码)在每个请求中发送,所以只有在安全的HTTPS连接中使用Basic Authentication才是安全的)
js
Authorization: Basic MTIzOjIxMw==
- 验证通过后,浏览器会将该次授权缓存一段时间,且每个请求会自动带上请求头
Authorization
认证信息
Authorization的value缓存在浏览器内部,经查验不存在cookie、localStorage等本地常用储存中,这个取决于浏览器的内部管理机制,暂不清楚具体清除时机。Basic Authentication的这种机制并不提供注销的方法。因为凭证是存储在浏览器内存中的,所以唯一的注销方法就是关闭或者手动清除浏览器缓存
TIP
js存在两个原生方法支持文本和base64的互转: btoa()和atob(), 但这两函数只能处理ASCII字符。因为中文字符不在ASCII字符集中,所以如果你直接传递一个包含中文的字符串给这两个函数,会抛出错误。但可以使用encodeURIComponent()和decodeURIComponent()函数与btoa()和atob()函数配合,从而让这两个函数可以处理包含中文的字符串。
Node实现
js
const http = require('http')
http
.createServer((req, res) => {
if (req.headers.authorization) {
// 可以解析base64,判断userId&password是否正确
res.write('hello world')
return res.end()
}
res.statusCode = 401
res.setHeader('WWW-Authenticate', 'Basic realm="Login"') // 给浏览器说明需要输入账号密码访问
res.end()
})
.listen(8132)