resourceOwnerPasswordGrant function

Future<Client> resourceOwnerPasswordGrant(
  1. Uri authorizationEndpoint,
  2. String username,
  3. String password, {
  4. String? identifier,
  5. String? secret,
  6. Iterable<String>? scopes,
  7. bool basicAuth = true,
  8. CredentialsRefreshedCallback? onCredentialsRefreshed,
  9. Client? httpClient,
  10. String? delimiter,
  11. Map<String, dynamic> getParameters(
    1. MediaType? contentType,
    2. String body
    )?,
})

Obtains credentials using a resource owner password grant.

This mode of authorization uses the user's username and password to obtain an authentication token, which can then be stored. This is safer than storing the username and password directly, but it should be avoided if any other authorization method is available, since it requires the user to provide their username and password to a third party (you).

The client identifier and secret may be issued by the server, and are used to identify and authenticate your specific OAuth2 client. These are usually global to the program using this library.

The specific permissions being requested from the authorization server may be specified via scopes. The scope strings are specific to the authorization server and may be found in its documentation. Note that you may not be granted access to every scope you request; you may check the Credentials.scopes field of Client.credentials to see which scopes you were granted.

The scope strings will be separated by the provided delimiter. This defaults to " ", the OAuth2 standard, but some APIs (such as Facebook's) use non-standard delimiters.

By default, this follows the OAuth2 spec and requires the server's responses to be in JSON format. However, some servers return non-standard response formats, which can be parsed using the getParameters function.

This function is passed the Content-Type header of the response as well as its body as a UTF-8-decoded string. It should return a map in the same format as the standard JSON response.

Implementation

Future<Client> resourceOwnerPasswordGrant(
    Uri authorizationEndpoint, String username, String password,
    {String? identifier,
    String? secret,
    Iterable<String>? scopes,
    bool basicAuth = true,
    CredentialsRefreshedCallback? onCredentialsRefreshed,
    http.Client? httpClient,
    String? delimiter,
    Map<String, dynamic> Function(MediaType? contentType, String body)?
        getParameters}) async {
  delimiter ??= ' ';
  var startTime = DateTime.now();

  var body = {
    'grant_type': 'password',
    'username': username,
    'password': password
  };

  var headers = <String, String>{};

  if (identifier != null) {
    if (basicAuth) {
      headers['Authorization'] = basicAuthHeader(identifier, secret!);
    } else {
      body['client_id'] = identifier;
      if (secret != null) body['client_secret'] = secret;
    }
  }

  if (scopes != null && scopes.isNotEmpty) {
    body['scope'] = scopes.join(delimiter);
  }

  httpClient ??= http.Client();
  var response = await httpClient.post(authorizationEndpoint,
      headers: headers, body: body);

  var credentials = handleAccessTokenResponse(
      response, authorizationEndpoint, startTime, scopes?.toList(), delimiter,
      getParameters: getParameters);
  return Client(credentials,
      identifier: identifier,
      secret: secret,
      httpClient: httpClient,
      onCredentialsRefreshed: onCredentialsRefreshed);
}