HTTP Basic Authorization
在HTTP中,Basic Authorization基本认证是一种用来允许Web浏览器或其他客户端程序在请求时提供用户名和口令形式的身份凭证的一种登录验证方式。
在发送之前是以用户名追加一个冒号然后串接上口令,并将得出的结果字符串再用Base64算法编码。例如,提供的用户名是Aladdin、口令是open sesame,则拼接后的结果就是Aladdin:open sesame,然后再将其用Base64编码,得到QWxhZGRpbjpvcGVuIHNlc2FtZQ==。最终将Base64编码的字符串发送出去,由接收者解码得到一个由冒号分隔的用户名和口令的字符串。
虽然对用户名和口令的Base64算法编码结果很难用肉眼识别解码,但它仍可以极为轻松地被计算机所解码,就像其容易编码一样。编码这一步骤的目的并不是安全与隐私,而是为将用户名和口令中的不兼容的字符转换为均与HTTP协议兼容的字符集。
------维基百科
一个典型的HTTP客户端和HTTP服务器的对话,服务器安装在同一台计算机上(localhost),包含以下步骤:
- 客户端请求一个需要身份认证的页面,但是没有提供用户名和口令。这通常是用户在地址栏输入一个URL,或是打开了一个指向该页面的链接。
- 服务端响应一个401应答码,并提供一个认证域。
- 接到应答后,客户端显示该认证域(通常是所访问的计算机或系统的描述)给用户并提示输入用户名和口令。此时用户可以选择确定或取消。
- 用户输入了用户名和口令后,客户端软件会在原先的请求上增加认证消息头(值是base64encode(username+":"+password)),然后重新发送再次尝试。
- 在本例中,服务器接受了该认证屏幕并返回了页面。如果用户凭据非法或无效,服务器可能再次返回401应答码,客户端可以再次提示用户输入口令.
一个包含基本认证的HTTP请求:
GET /private/index.html HTTP/1.0 Host: localhost Authorization: Basic QWxhZGRpbjpvcGVuIHNlc2FtZQ==
base64
Python中的base64模块可以通过base64、base32或base 16编码将二进制数据编码/解码为文本。
上面例子中的用户名为"Aladdin", password为 "open sesame":
>>> import base64 >>> print base64.b64encode('Aladdin:open sesame') QWxhZGRpbjpvcGVuIHNlc2FtZQ== >>> print base64.b64decode('QWxhZGRpbjpvcGVuIHNlc2FtZQ==') Aladdin:open sesame
urllib2
python标准库中使用urllib2来处理基本认证。urllib2.HTTPBasicAuthHandler()处理程序可用add_password()来设置认证。
h.add_password(realm,uri,user,passwd)
realm是与验证相关联的名称或描述信息,取决于远程服务器。uri是基URL。user和passwd分别指定用户名和密码。
import urllib2 auth=urllib2.HTTPBasicAuthHandler() auth.add_password('Administrator','http://www.example.com','Dave','123456') opener=urllib2.build_opener(auth) u=opener.open('http://www.example.com/evilplan.html')
源码中的base64编码方式:
raw = "%s:%s" % (user, pw) auth = 'Basic %s' % base64.b64encode(raw).strip()
requests
还有一个很常用的requests库,其中处理基本认证:
import requests requests.get('https://api.github.com/user', auth=requests.auth.HTTPBasicAuth('user', 'pass'))
因为HTTP Basic Auth很常用,所以也可以直接验证:
>>> requests.get('https://api.github.com/user', auth=('user', 'pass')) <Response [200]>
或者用request.Session()保持认证状态:
s = requests.Session() s.auth = ('user', 'pass') s.get('http://httpbin.org/')
源码中的base64编码方式:
def _basic_auth_str(username, password): """Returns a Basic Auth string.""" return 'Basic ' + base64.b64encode(('%s:%s' % (username, password)).encode('latin1')).strip().decode('latin1')