Skip to content

Conversation

zendesk-mradmacher
Copy link

@zendesk-mradmacher zendesk-mradmacher commented Oct 8, 2025

Add support for refreshing OAuth access token.

When you need some inspiration, consult how the token refresh flow is done by Restforce, the public gem for Salesforce REST API.

I propose adding a new ZendeskAPI::TokenRefresher service, to obtain new access and refresh tokens. It takes client configuration as a parameter. When tokens get refreshed, the client configuration is updated, so the next requests are issued using the newly obtained access token. Also a block is yielded with new access and refresh tokens, so they could be stored for further use.

The alternative solution is to use ZendeskAPI::Middleware::Response::TokenRefresher, to start the process of token refreshing each time when the API responds with 401. The middleware also updates the client configuration. It requires a callback to be configured. The called is called whenever new tokens are obtained to allow storing them for further use.

How to test?

In Admin Center, Apps and Integrations / APIs / OAuth Clients create a new client. Note client id and secret and redirect URL. The redirect URL can be any address.

  • Login to Zendesk as an user.
  • Assumming your Zendesk subdomain is "testing", open the following URL in browser:
https://testing.zendesk.com/oauth/authorizations/new?client_id=<your client id>&response_type=code&redirect_uri=<encoded redirect URL>&scope=read

The encoded URL looks like https%3A%2F%2Fexample.com.

  • Accept the authorization and intercept the code issued to the redirect URL.
  • Request for access and refresh tokens using the intercepted code:
curl https://testing.zendesk.com/oauth/tokens \
  -H "Content-Type: application/json" \
  -d '{"grant_type": "authorization_code", "code": "<here goes the code>", "client_id": "<your client id>", "client_secret": "<your client secret>", "redirect_uri": "<your redirect URL", "scope": "read", "expires_in": 300 }' \
  -X POST

expires_in is chosen to be 5 minutes (the lowest possible value), to make the access token expire quickly, for easier testing.

  • Save tokens in a file named tokens in the following format:
<access token>,<refresh token>
  • Use the following Ruby script to make requests to your Zendesk. Observe how tokens are refreshed upon expiring.
require 'zendesk_api'

# `tokens` is a one line file that stores comma separated tokens:
# <access token>,<refresh token>
access_token, refresh_token = File.open("tokens") do |file|
  file.read.strip.split(",")
end

client = ZendeskAPI::Client.new do |config|
  # Mandatory:
  config.url = "https://testing.zendesk.com/api/v2"

  config.client_id = "<your client id>"
  config.client_secret = "<your client secret>"
  config.access_token_expiration = 300 # expire quickly to observe token refreshing

  config.access_token = access_token
  config.refresh_token = refresh_token

  # In case of using the middleware for refreshing tokens, update the storage with new tokens
  # config.refresh_token_callback = lambda do |access_token, refresh_token|
  #   File.open("tokens", "w") do |file|
  #     file.write("#{access_token},#{refresh_token}")
  #   end
  # end

  require 'logger'
  config.logger = Logger.new(STDOUT)
end

users = client.users.per_page(1)
begin
  # A request with an expired access token is made.
  users.fetch!
  # The request is rejected with 401 status code.
rescue ZendeskAPI::Error::Unauthorized
  # Refresh tokens and store them securely
  ZendeskAPI::TokenRefresher.new(client.config).refresh_token do |access_token, refresh_token|
    File.open("tokens", "w") do |file|
      file.write("#{access_token},#{refresh_token}")
    end
  end
  # Issue the request again.
  users.fetch!
end

@zendesk-mradmacher zendesk-mradmacher requested a review from a team October 13, 2025 11:26
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant