blob: c6d34b94cd94f6fcec88c91ca390cffbb7b72805 [file] [log] [blame]
// Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
import 'dart:async';
import 'package:http/http.dart' as http;
import 'package:http_parser/http_parser.dart';
import 'client.dart';
import 'handle_access_token_response.dart';
import 'utils.dart';
/// Obtains credentials using a [client credentials grant](
/// This mode of authorization uses the client's [identifier] and [secret]
/// to obtain an authorization token from the authorization server, instead
/// of sending a user through a dedicated flow.
/// The client [identifier] and [secret] are required, 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](
Future<Client> clientCredentialsGrant(
Uri authorizationEndpoint, String identifier, String secret,
{Iterable<String> scopes,
bool basicAuth = true,
http.Client httpClient,
String delimiter,
Map<String, dynamic> Function(MediaType contentType, String body)
getParameters}) async {
delimiter ??= ' ';
var startTime =;
var body = {'grant_type': 'client_credentials'};
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,
headers: headers, body: body);
var credentials = await handleAccessTokenResponse(
response, authorizationEndpoint, startTime, scopes, delimiter,
getParameters: getParameters);
return Client(credentials,
identifier: identifier, secret: secret, httpClient: httpClient);