docs: def validate(self, request):
      """ Check that a Client's authorization request is valid.
  
      If the request is invalid or malformed in any way, raises the appropriate
      exception.  Read `the relevant section of the specification
      <http://tools.ietf.org/html/rfc6749#section-4.1 .>`_ for descriptions of
      each type of error.
  
      :raises: a :py:class:`AuthorizationError` if the request is invalid.
      """
  
      # From http://tools.ietf.org/html/rfc6749#section-3.1 :
      #
      #     The authorization server MUST support the use of the HTTP "GET"
      #     method [RFC2616] for the authorization endpoint and MAY support the
      #     use of the "POST" method as well.
      #
      if not request.method in ['GET', 'POST']:
        raise InvalidRequest('must be GET or POST request')
  
      if settings.DJOAUTH2_SSL_ONLY and not request.is_secure():
        raise InvalidRequest('all requests must use TLS')
  
      self.request = request
      self.user = request.user
      if not self.user.is_authenticated():
        raise UnauthenticatedUser('user must be authenticated')
  
      client_id = request.REQUEST.get('client_id')
      if not client_id:
        raise InvalidRequest('no "client_id" provided')
  
      try:
        self.client = Client.objects.get(key=client_id)
      except Client.DoesNotExist:
        raise InvalidRequest('"client_id" does not exist')
  
      # From http://tools.ietf.org/html/rfc6749#section-3.1.2.3 :
      #
      #     If multiple redirection URIs have been registered, if only part of
      #     the redirection URI has been registered, or if no redirection URI has
      #     been registered, the client MUST include a redirection URI with the
      #     authorization request using the "redirect_uri" request parameter.
      #
      self.request_redirect_uri = request.REQUEST.get('redirect_uri')
      if not (self.client.redirect_uri or self.request_redirect_uri):
        raise InvalidRequest('no "redirect_uri" provided or registered')
  
      # From http://tools.ietf.org/html/rfc6749#section-3.1.2.3 :
      #
      #     When a redirection URI is included in an authorization request, the
      #     authorization server MUST compare and match the value received
      #     against at least one of the registered redirection URIs (or URI
      #     components) as defined in [RFC3986] Section 6, if any redirection
      #     URIs were registered.  If the client registration included the full
      #     redirection URI, the authorization server MUST compare the two URIs
      #     using simple string comparison as defined in [RFC3986] Section 6.2.1.
      #
      if (self.client.redirect_uri and
            self.request_redirect_uri and
            self.client.redirect_uri != self.request_redirect_uri):
        raise InvalidRequest('"redirect_uri" does not matched the registered URI')
  
      # From http://tools.ietf.org/html/rfc6749#section-3.1.2 :
      #
      #     The redirection endpoint URI MUST be an absolute URI as defined by
      #     [RFC3986] Section 4.3.
      #
      redirect_uri = self.client.redirect_uri or self.request_redirect_uri
      if not absolute_http_url_re.match(redirect_uri):
        raise InvalidRequest('"redirect_uri" must be absolute')
  
      # From http://tools.ietf.org/html/rfc6749#section-3.1.2 :
      #
      #     The endpoint URI MUST NOT include a fragment component.
      #
      if urlparse(redirect_uri).fragment:
        raise InvalidRequest('"redirect_uri" must not contain a fragment')
  
      # From http://tools.ietf.org/html/rfc6749#section-3.1.2.1 :
      #
      #     The redirection endpoint SHOULD require the use of TLS as described
      #     in Section 1.6 when the requested response type is "code" or "token",
      #     or when the redirection request will result in the transmission of
      #     sensitive credentials over an open network.  This specification does
      #     not mandate the use of TLS because at the time of this writing,
      #     requiring clients to deploy TLS is a significant hurdle for many
      #     client developers.  If TLS is not available, the authorization server
      #     SHOULD warn the resource owner about the insecure endpoint prior to
      #     redirection (e.g., display a message during the authorization
      #     request).
      #
      if (settings.DJOAUTH2_SSL_ONLY and
          urlparse(redirect_uri).scheme != 'https'):
        raise InvalidRequest('"redirect_uri" must use TLS')
  
      # Only store the redirect_uri value if it validates successfully. The
      # 'make_error_redirect' method will use the 'missing_redirect_uri' passed
      # to the '__init__' method if 'self.redirect_uri' is None.
      self.redirect_uri = redirect_uri
  
      # From http://tools.ietf.org/html/rfc6749#section-3.1.1 :
      #
      #     The client informs the authorization server of the desired grant type
      #     using the following parameter:
      #
      #     response_type
      #           REQUIRED.  The value MUST be one of "code" for requesting an
      #           authorization code as described by Section 4.1.1, "token" for
      #           requesting an access token (implicit grant) as described by
      #           Section 4.2.1, or a registered extension value as described by
      #           Section 8.4.
      #
      # This implementation only supports the "code" "response_type".
      response_type = request.REQUEST.get('response_type')
      if response_type != 'code':
        raise UnsupportedResponseType('"response_type" must be "code"')
  
      # As recommended by http://tools.ietf.org/html/rfc6749#section-4.1.1 :
      #
      #     state
      #           RECOMMENDED.  An opaque value used by the client to maintain
      #           state between the request and callback.  The authorization
      #           server includes this value when redirecting the user-agent back
      #           to the client.  The parameter SHOULD be used for preventing
      #           cross-site request forgery as described in Section 10.12.
      #
      # and necessary for the CSRF recommendation mandated by
      # http://tools.ietf.org/html/rfc6749#section-10.12 :
      #
      #     The client MUST implement CSRF protection for its redirection URI.
      #     This is typically accomplished by requiring any request sent to the
      #     redirection URI endpoint to include a value that binds the request to
      #     the user-agent's authenticated state (e.g., a hash of the session
      #     cookie used to authenticate the user-agent).  The client SHOULD
      #     utilize the "state" request parameter to deliver this value to the
      #     authorization server when making an authorization request.
      #
      self.state = request.REQUEST.get('state')
      if settings.DJOAUTH2_REQUIRE_STATE and not self.state:
        raise InvalidRequest('"state" must be included')
  
      requested_scope_string = request.REQUEST.get('scope', '')
      if not requested_scope_string:
        raise InvalidScope('"scope" must be included')
  
      requested_scope_names = set(requested_scope_string.split(' '))
      self.valid_scope_objects = Scope.objects.filter(
          name__in=requested_scope_names)
      valid_scope_names = {scope.name for scope in self.valid_scope_objects}
      if valid_scope_names < requested_scope_names:
        raise InvalidScope('The following scopes are invalid: {}'.format(
            ', '.join('"{}"'.format(name)
                      for name in (requested_scope_names - valid_scope_names))))