curl -u 背后的内容以及和 Django rest framework 的 BasicAuthentication 的呼应

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:[email protected]/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。

你可能感兴趣的:(Linux,Django,#,auth,django,python,restful)