Class: Spotted::Auth

Inherits:
Object
  • Object
show all
Defined in:
lib/spotted/auth.rb

Overview

Handles OAuth 2.0 authorization flows for Spotify API

Constant Summary collapse

AUTHORIZE_URL =
"https://accounts.spotify.com/authorize"
TOKEN_URL =
"https://accounts.spotify.com/api/token"

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(client_id:, client_secret:) ⇒ Auth

Creates a new Auth instance for handling OAuth flows

Parameters:

  • client_id (String)

    The Spotify application client ID

  • client_secret (String)

    The Spotify application client secret

Raises:

  • (ArgumentError)

    if client_id or client_secret is missing



21
22
23
24
25
26
27
28
29
30
31
32
# File 'lib/spotted/auth.rb', line 21

def initialize(client_id:, client_secret:)
  if client_id.nil? || client_id.empty?
    raise ArgumentError, "client_id is required"
  end

  if client_secret.nil? || client_secret.empty?
    raise ArgumentError, "client_secret is required"
  end

  @client_id = client_id
  @client_secret = client_secret
end

Instance Attribute Details

#client_idString (readonly)

Returns:

  • (String)


10
11
12
# File 'lib/spotted/auth.rb', line 10

def client_id
  @client_id
end

#client_secretString (readonly)

Returns:

  • (String)


13
14
15
# File 'lib/spotted/auth.rb', line 13

def client_secret
  @client_secret
end

Instance Method Details

#authorization_url(redirect_uri:, scope: nil, state: nil, show_dialog: false) ⇒ String

Generates the Spotify authorization URL for OAuth2 authorization code flow

Examples:

Basic usage

auth = Spotted::Auth.new(client_id: "...", client_secret: "...")
url = auth.authorization_url(redirect_uri: "http://localhost:3000/callback")

With scopes and state

url = auth.authorization_url(
  redirect_uri: "http://localhost:3000/callback",
  scope: ["user-read-private", "user-read-email"],
  state: "random_state_string"
)

Parameters:

  • redirect_uri (String)

    The URI to redirect to after authorization

  • scope (String, Array<String>, nil) (defaults to: nil)

    Space-delimited string or array of authorization scopes

  • state (String, nil) (defaults to: nil)

    Optional state parameter for CSRF protection

  • show_dialog (Boolean) (defaults to: false)

    Whether to force the user to approve the app again

Returns:

  • (String)

    The authorization URL to redirect the user to



53
54
55
56
57
58
59
60
61
62
63
64
65
66
# File 'lib/spotted/auth.rb', line 53

def authorization_url(redirect_uri:, scope: nil, state: nil, show_dialog: false)
  params = {
    client_id: @client_id,
    response_type: "code",
    redirect_uri: redirect_uri
  }

  params[:scope] = scope.is_a?(Array) ? scope.join(" ") : scope if scope
  params[:state] = state if state
  params[:show_dialog] = "true" if show_dialog

  query_string = URI.encode_www_form(params)
  "#{AUTHORIZE_URL}?#{query_string}"
end

#exchange_authorization_code(code:, redirect_uri:) ⇒ Hash

Exchanges an authorization code for an access token

Examples:

auth = Spotted::Auth.new(client_id: "...", client_secret: "...")
credentials = auth.exchange_authorization_code(
  code: params[:code],
  redirect_uri: "http://localhost:3000/callback"
)
access_token = credentials[:access_token]

Parameters:

  • code (String)

    The authorization code received from the authorization callback

  • redirect_uri (String)

    The redirect URI used in the authorization request (must match exactly)

Returns:

  • (Hash)

    Token response containing:

    • access_token [String] The access token to use for API requests

    • token_type [String] The type of token (usually “Bearer”)

    • expires_in [Integer] Number of seconds until the token expires

    • refresh_token [String] Token to use to refresh the access token

    • scope [String] Space-delimited list of granted scopes

Raises:

  • (Spotted::APIError)

    if the token exchange fails



89
90
91
92
93
94
95
96
97
# File 'lib/spotted/auth.rb', line 89

def exchange_authorization_code(code:, redirect_uri:)
  body = URI.encode_www_form(
    grant_type: "authorization_code",
    code: code,
    redirect_uri: redirect_uri
  )

  make_token_request(body: body)
end

#refresh_access_token(refresh_token:) ⇒ Hash

Refreshes an access token using a refresh token

Examples:

auth = Spotted::Auth.new(client_id: "...", client_secret: "...")
credentials = auth.refresh_access_token(refresh_token: stored_refresh_token)
new_access_token = credentials[:access_token]

Parameters:

  • refresh_token (String)

    The refresh token received from a previous authorization

Returns:

  • (Hash)

    Token response containing:

    • access_token [String] The new access token to use for API requests

    • token_type [String] The type of token (usually “Bearer”)

    • expires_in [Integer] Number of seconds until the token expires

    • scope [String] Space-delimited list of granted scopes

Raises:

  • (Spotted::APIError)

    if the token refresh fails



115
116
117
118
119
120
121
122
# File 'lib/spotted/auth.rb', line 115

def refresh_access_token(refresh_token:)
  body = URI.encode_www_form(
    grant_type: "refresh_token",
    refresh_token: refresh_token
  )

  make_token_request(body: body)
end