Anyone starting to work with SugarCRM REST API and their OAuth2 flow will notice how unusual their OAuth implementation is. After working with OAuth2 flows from Google, Microsoft, Salesforce,… Sugar’s model can really throw you off. So we wanted to share our experience here.

OAuth Grant Type

To get the initial access and refresh tokens, you will have to use the legacy grant type ‘password’. Most other API providers implement ‘authorization code’ grant.

Oauth2

ClientId, no ClientSecret

Usually, a developer registers with a platform to get appId+appSecret for his(her) app, but SugarCRM does not require you to do so. Not having to register your app was also quite unexpected. You always use “sugar” for the clientId, without any secret.

The client_id of “sugar” will automatically create an OAuth Key in the system and can be used for “password” authentication. The client_id of “support_portal” will create an OAuth Key if the portal system is enabled and will allow for portal authentication. Other client_id’s can be created by the administrator in the OAuthKeys section in the Administration section and can be used in the future for additional grant types, if the client secret is filled in, it will be checked to validate the use of the client id.

Platform

Another big surprise was that you have to ask your users to register a separate API platform because if you use the default one (“base”) your access tokens will keep going bad. They have a weird mechanism where the Sugar logins interfere with API tokens:

Normally, when logging into Sugar, users log in with a platform type of “base”. We are using “custom” to avoid any potential login conflicts.

Refresh token woes

And the most unintuitive behavior is with the refresh tokens. It seems like only one set of refresh tokens per platform key exists on their servers at any given time, as refreshing an access token invalidates all earlier obtained refresh tokens. So you have to be very careful with parallel connections!

Say your two connections hit 401 Unauthorized or an access token expiration:

  1. 1st thread uses refresh token A to get a new access token B and a new refresh token B.
  2. Also, 2nd thread uses refresh token A to get a new access token C and a new refresh token C.
  3. Both access tokens B and C are valid and can be used until they expire.
  4. But the refresh token B is invalid because 2nd refresh invalidated it. Only the refresh token C is valid now.
  5. If you happened to save the refresh token B and not C, and try to use it in the future, you will get this error: {"error":"invalid_grant","error_message":"Invalid refresh token"}
  6. An hour later, your access token B has expired, and you can’t refresh it anymore.

We spent much time investigating this multi-connection problem. OAuth2 implementations from Google or Microsoft allow you to have multiple refresh tokens which don’t interfere with each other, and usually, no ‘platform’ concept is required. The quirks of Sugar’s Oauth2 implementation are not documented well either.

Why SugarCRM

At Aurinko, we are building a virtual CRM API which allows developers to define dynamic unified API’s and SugarCRM is one of connectors that we support.