Skip to content

Providing additional parameters and headers when authorizing and acquiring tokens? #12

@Rob-bie

Description

@Rob-bie

Based on the samples and a quick look through the source this appears to not be possible. I discovered that I am unable to use this library with Reddit's API because it requires additional parameters and an additional header when authorizing and grabbing tokens. More specifically, it expects state and duration parameters when authorizing. Also, when acquiring access (and refreshing) tokens, it requires a basic auth header. You can find out more here. As a possible solution, perhaps we could expand the config struct with a couple more fields and add some accompanying functionality?

authorize_options: nil
token_options:     nil

This would allow us to write a configuration like this:

 %OAuth2Ex.Config{
       ...
       authorize_options: [parameters: [duration: "permanent", ...]]
       token_options:     [parameters: [...], headers: [{"Authorization", "..."}]]
       ...
 }

By making the parameters value a keyword list and the headers value a list of tuples, we can easily merge them with the other parameters and default headers. (I'm not sure that I like this inconsistency but it's more convenient from an implementation standpoint)

Inside of oauth2ex.ex we could provide some defaults:

def config(params) do
  %OAuth2Ex.Config{
        ...
        authorize_options: params[:authorize_options] || [parameters: []]
        token_options:     params[:token_options] || [parameters: [], headers: []]
        ...
   }
end

And here's an example of a change we'd have to make:

def get_token(config, code) do
  query_params = [
    client_id:     config.id,
    client_secret: config.secret,
    redirect_uri:  config.callback_url,
    code:          code,
    grant_type:    "authorization_code"
  ] 
  |> Keyword.merge(config.token_options[:parameters] || [])
  |> URI.encode_query

  do_get_token(config, query_params)
end

and for headers

defp do_get_token(config, query_params) do
  headers = [
    {"Content-Type", "application/x-www-form-urlencoded"},
    {"Accept", "application/json"}
  ] ++ (config.token_options[:headers] || [])

  HTTPoison.post!(config.token_url, [query_params], headers).body
  |> JSX.decode!
  |> parse_token(config)
end

This should cover the cases where people provide no additional headers or parameters, when they provide one but not the other and, when they provide neither. This is just a quick write up, there's some other modifications that would have to be made to accommodate this functionality. This should increase the coverage of the library, making more APIs accessible. I found this functionality in other OAuth2 libraries but they lack certain features that initially attracted me to this one.

Thoughts and comments? I will research more thoroughly and take care of this if it's deemed worth while.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions