curl -u 的基本介绍
curl 是常用的命令行工具,用来请求 Web 服务器。它的名字就是客户端(client)的 URL 工具的意思。它的功能非常强大,命令行参数多达几十种。如果熟练的话,完全可以取代 Postman 这一类的图形界面工具。
-u参数用来设置服务器认证的用户名和密码。
$ curl -u 'bob:12345' https://google.com/login
$ 等同于
$ curl -v -H 'Authorization: Basic Ym9iOjEyMzQ1' https://google.com/login
$
$ python
Python 2.7.10 (default, Feb 24 2017, 08:42:51)
[GCC 4.4.7 20120313 (Red Hat 4.4.7-4)] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> import base64
>>> base64.b64decode('Ym9iOjEyMzQ1')
'bob:12345'
>>> base64.b64encode('bob:12345')
'Ym9iOjEyMzQ1'
>>>
上面命令设置用户名为 bob,密码为12345,然后将其 ( 通过base64编码 )转为 HTTP 标头Authorization: Basic Ym9iOjEyMzQ1。
curl 能够识别 URL 里面的用户名和密码。
$ curl https://bob:12345@google.com/login
上面命令能够识别 URL 里面的用户名和密码,将其转为上个例子里面的 HTTP 标头。
$ curl -u 'bob' https://google.com/login
上面命令只设置了用户名,执行后,curl 会提示用户输入密码。
Django rest framework 的认证类 BasicAuthentication
D:\path\to\site-packages\rest_framework\authentication.py
class BasicAuthentication(BaseAuthentication):
"""
HTTP Basic authentication against username/password.
"""
www_authenticate_realm = 'api'
def authenticate(self, request):
"""
Returns a `User` if a correct username and password have been supplied
using HTTP Basic authentication. Otherwise returns `None`.
"""
auth = get_authorization_header(request).split()
if not auth or auth[0].lower() != b'basic':
return None
if len(auth) == 1:
msg = _('Invalid basic header. No credentials provided.')
raise exceptions.AuthenticationFailed(msg)
elif len(auth) > 2:
msg = _('Invalid basic header. Credentials string should not contain spaces.')
raise exceptions.AuthenticationFailed(msg)
try:
auth_parts = base64.b64decode(auth[1]).decode(HTTP_HEADER_ENCODING).partition(':')
except (TypeError, UnicodeDecodeError, binascii.Error):
msg = _('Invalid basic header. Credentials not correctly base64 encoded.')
raise exceptions.AuthenticationFailed(msg)
userid, password = auth_parts[0], auth_parts[2]
return self.authenticate_credentials(userid, password, request)
def authenticate_credentials(self, userid, password, request=None):
"""
Authenticate the userid and password against username and password
with optional request for context.
"""
credentials = {
get_user_model().USERNAME_FIELD: userid,
'password': password
}
user = authenticate(request=request, **credentials)
if user is None:
raise exceptions.AuthenticationFailed(_('Invalid username/password.'))
if not user.is_active:
raise exceptions.AuthenticationFailed(_('User inactive or deleted.'))
return (user, None)
def authenticate_header(self, request):
return 'Basic realm="%s"' % self.www_authenticate_realm
当然需要在 settings.py 中指定 DEFAULT_AUTHENTICATION_CLASSES 为 BasicAuthentication:
REST_FRAMEWORK = {
'DEFAULT_AUTHENTICATION_CLASSES': (
'rest_framework.authentication.BasicAuthentication',
),
}
demo:
这样我们就可以用 curl --user ‘username:password’ -X GET -H ‘Content_type: application/json’ ‘http://domain:port/test/’ 可以通过认证并得到正确 response。