Method: Ably::Auth#create_token_request

Defined in:
lib/submodules/ably-ruby/lib/ably/auth.rb

#create_token_request(token_params = {}, auth_options = {}) ⇒ Models::TokenRequest

Creates and signs an Models::TokenRequest based on the specified (or if none specified, the client library stored) ‘token_params` and `auth_options`. Note this can only be used when the API key value is available locally. Otherwise, the Models::TokenRequest must be obtained from the key owner. Use this to generate an Models::TokenRequest in order to implement an Ably Token request callback for use by other clients. Both `token_params` and `auth_options` are optional. When omitted or null, the default token parameters and authentication options for the client library are used, as specified in the `client_options` when the client library was instantiated, or later updated with an explicit authorize request. Values passed in are used instead of, rather than being merged with, the default values. To understand why an Models::TokenRequest may be issued to clients in favor of a token, see Token Authentication explained.

Examples:

client.auth.create_token_request({ ttl: 3600 }, { id: 'asd.asd' })
#<Ably::Models::TokenRequest:0x007fd5d919df78
#  @hash={
#   :id=>"asds.adsa",
#   :clientId=>nil,
#   :ttl=>3600000,
#   :timestamp=>1428973674000,
#   :capability=>"{\"*\":[\"*\"]}",
#   :nonce=>"95e543b88299f6bae83df9b12fbd1ecd",
#   :mac=>"881oZHeFo6oMim7....uE56a8gUxHw="
#  }
#>>

Parameters:

  • token_params (Hash) (defaults to: {})

    the token params used in the token request

  • auth_options (Hash) (defaults to: {})

    the authentication options for the token request

Options Hash (token_params):

  • :client_id (String)

    A client ID to associate with this token. The generated token may be used to authenticate as this client_id

  • :ttl (Integer)

    validity time in seconds for the requested Models::TokenDetails. Limits may apply, see https://www.ably.com/docs/general/authentication

  • :capability (Hash)

    canonicalised representation of the resource paths and associated operations

  • :timestamp (Time)

    the time of the request

  • :nonce (String)

    an unquoted, unescaped random string of at least 16 characters

Options Hash (auth_options):

  • :key (String)

    API key comprising the key name and key secret in a single string

  • :client_id (String)

    client ID identifying this connection to other clients (will use client_id specified when library was instanced if provided)

  • :query_time (Boolean)

    when true will query the Ably system for the current time instead of using the local time

  • :token_params (Hash)

    convenience to pass in token_params within the auth_options argument, especially useful when setting default token_params in the client constructor

Returns:

Raises:



309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
# File 'lib/submodules/ably-ruby/lib/ably/auth.rb', line 309

def create_token_request(token_params = {}, auth_options = {})
  ensure_valid_auth_attributes auth_options

  auth_options = auth_options.dup
  token_params = (auth_options[:token_params] || {}).merge(token_params)

  split_api_key_into_key_and_secret! auth_options if auth_options[:key]
  request_key_name   = auth_options.delete(:key_name) || key_name
  request_key_secret = auth_options.delete(:key_secret) || key_secret

  raise Ably::Exceptions::TokenRequestFailed, 'Key Name and Key Secret are required to generate a new token request' unless request_key_name && request_key_secret

  ensure_current_time_is_based_on_server_time if auth_options[:query_time]
  timestamp = token_params.delete(:timestamp) || current_time
  timestamp = Time.at(timestamp) if timestamp.kind_of?(Integer)



  token_request = {
    keyName:    request_key_name,
    timestamp:  (timestamp.to_f * 1000).round,
    nonce:      token_params[:nonce] || SecureRandom.hex.force_encoding('UTF-8')
  }

  token_client_id = token_params[:client_id] || auth_options[:client_id] || client_id
  token_request[:clientId] = token_client_id if token_client_id

  if token_params[:ttl]
    token_ttl = [
      token_params[:ttl],
      Ably::Models::TokenDetails::TOKEN_EXPIRY_BUFFER + TOKEN_DEFAULTS.fetch(:renew_token_buffer) # never issue a token that will be immediately considered expired due to the buffer
    ].max
    token_request[:ttl] = (token_ttl * 1000).to_i
  end

  token_request[:capability] = token_params[:capability] if token_params[:capability]
  if token_request[:capability].is_a?(Hash)
    lexicographic_ordered_capabilities = Hash[
      token_request[:capability].sort_by { |key, value| key }.map do |key, value|
        [key, value.sort]
      end
    ]
    token_request[:capability] = JSON.dump(lexicographic_ordered_capabilities)
  end

  token_request[:mac] = sign_params(token_request, request_key_secret)

  # Undocumented feature to request a persisted token
  token_request[:persisted] = token_params[:persisted] if token_params[:persisted]

  Models::TokenRequest.new(token_request)
end