docs: function (req, provider, callback) {
      var config = req.app.get('stormpathConfig');
      var baseUrl = config.web.baseUrl || req.protocol + '://' + getHost(req);
      var code = req.query.code;
      var oauthStateToken = req.cookies.oauthStateToken;
      var options = {
        form: {
          grant_type: 'authorization_code',
          code: code,
          redirect_uri: baseUrl + provider.uri,
          client_id: config.authorizationServerClientId,
          client_secret: config.authorizationServerClientSecret,
          state: oauthStateToken
        },
        headers: {
          Accept: 'application/json'
        }
      };
  
      var authUrl = config.org + 'oauth2/' + config.authorizationServerId + '/v1/token';
  
      request.post(authUrl, options, function (err, result, body) {
        var parsedBody;
  
        if (err) {
          return callback(err);
        }
  
        var contentType = result.headers['content-type'] || '';
  
        if (contentType.indexOf('text/plain') === 0) {
          parsedBody = qs.parse(body);
        } else {
          try {
            parsedBody = JSON.parse(body);
          } catch (err) {
            return callback(err);
          }
  
          if (parsedBody.error) {
            return callback(new Error(parsedBody.error_description));
          }
        }
  
        if (!parsedBody || typeof parsedBody !== 'object' || !parsedBody.access_token) {
          return callback(new Error('Unable to parse response when exchanging an authorization code for an access token.'));
        }
  
        callback(null, parsedBody);
      });
    }