schmorrison / Zoho

Golang API for Zoho services

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

API: Refresh Tokens not received in OAuth2 flow

schmorrison opened this issue · comments

Zohos OAuth2 flow no longer returns "refresh_token" in the resposne JSON. This issue prevents applications from renewing the access tokens and as a result do not run long than 1-hour without needing re-consent via the browser.

This is a critical issue. A ticket has been submitted to Zoho.

Thanks @schmorrison for highlighting this issue. This point has been hampering me in building my backend server with zoho crm integration.

@ysahil97 I have recently had success using the "self-client" option again. Though the mechanism is a little weird and limiting.

  1. You can create a "self-client" api key/secret at: Zoho Developer API Console
  2. Then you can click on the "self-client" you just created (you can only create 1 per account it seems like) and you can fill out the scopes and expiry time (1-10mins) and can receive a "code".
  3. The code then can be used in zoho.GenerateTokenRequest() to receive a valid token and refresh token. The only limitation this poses is the token needs to be first retrieved within the expiry time set for the code in step 2, and the token needs to be refreshed with zoho.RefreshTokenRequest() every 60-minutes (API requests should issue a refresh automatically though)
    image
    image

"Refresh Token: Used to obtain a new access token after the old one expires. A refresh token does not expire. The maximum number of allowed refresh tokens per account is 20. The 21st refresh token will replace the first created refresh token."

This seems to suggest that applications running with self-client api tokens will need to be restarted with a new "code" if they miss a refresh window. And that a single account is limited to 20 applications running with self-client api tokens.

This could be a good target for a PR, better token management. possible options maybe:

  • a goroutine that just automatically runs continuously to refresh tokens on time.
  • a small CLI that constantly refreshes the tokens for all zoho credentials on the machine
  • a HTTP endpoint that can be used to manage the multiple refresh tokens so programs to race eachother for the limited tokens.

I haven't tried obtaining an api token via the zoho.AuthorizationCodeRequest() using a regular domain name (ie. not localhost) as the redirect URL. They may have included a limitation to that effect. Are you using a localhost redirect URL?

Isn't this solved by requesting the authorization code with the "prompt=consent&access_type=offline" flow?

@ArneZsng I don't remember the prompt=consent parameter in the OAuth flow, this code certainly doesn't know about it. If you can link to a doc that gives that option on the request that would be awesome.

I've seen your pull request and will review it in a few hours when i return from work.

AFAIK this issue is unresolved for the prompt type flow. I may have time to test for a refresh token tonight.

@schmorrison I found it here: https://www.zoho.com/accounts/protocol/oauth/web-apps/authorization.html

To quote:

access_type - Value can be 'offline' or 'online'. If the value is offline, you will receive a refresh token along with an access token for the first time you make the request. Once the access token expires you can use the refresh token to regenerate them. Whereas if the value is online, you will receive only an access token. If you forget your refresh token or cannot access it, use the following parameter along with access_type to receive a new refresh token.
Note: If the access_type is not mentioned as offline, by default it will be considered as online.
prompt - Value must be 'consent'. If this parameter is included in the query, every time you generate an OAuth token, the user's consent approval will be mandatory.
Example: To receive another refresh token, include access_type=offline and prompt=consent in your authorization request.

If I include the prompt=consent flag in the original authorization request, I do get a refresh token and an access token in exchange for the auth code.

Hope this helps!

I'll address this tonight, unless you beat me to it. ;)

Not today, we are triggering the flow from our frontend web app, so I did not touch that part yet. :)