5

I have the following issue and need an advice on how to approach it.

I connect to a third party system which generates a JWT token. The problem is that the token expires every 15 minutes and I'am not allowed to refresh it constantly due to the authentication system.

Heres a breakdown:

  • Token is too long 700 characters and can't be stored in a custom setting/custom metadata type.

  • Even if I split the token in a few fields I'am still not able to refresh and store it before it expires because you are not allowed to have a DML and a callout in the same transaction.

I don't really want to use a custom object just for the token but is there any other solution here?

5
  • 3
    You can have Callout + DML in the same transaction. Callout just has to come first.
    – Adrian Larson
    Mar 22, 2017 at 13:04
  • And what is problem with creating 3 fields to store token? I have seen that couple of times in different managed packages
    – kurunve
    Mar 22, 2017 at 13:06
  • Moving the callout at the start wouldn't be useful as I need to be checking if the token is still valid at the beginning. Otherwise I'll be trying to connect with expired credentials. Mar 22, 2017 at 13:06
  • 3
    If only you could update Named Credentials from Apex, they'd be a good fit here. I'm not sure either way if it's possible.
    – Adrian Larson
    Mar 22, 2017 at 13:07
  • 3
    What is also possible to do -- save last callout date/time and in case if that is more than 15 minutes ago -- get new credentials. Also, next case may take a place -- do regular callout, and in case if token expired -- refresh token and repeat callout. As long as those are not in loops -- it should work fine
    – kurunve
    Mar 22, 2017 at 13:11

1 Answer 1

3

Okay, so you can actually update the OAuth Token for a Named Credential using the Metadata API. If you install the Apex Wrapper Salesforce Metadata API, you can push the new token with an additional callout, and not even worry about mixing callouts and DML (though it would be fine if you put the DML at the end).

Anyway, your code would look something like:

// retrieve new token value

MetadataService.NamedCredential credential = new MetadataService.NamedCredential();
credential.fullName = 'Demo_Credential';
credential.label = 'Demo Credential';
credential.endpoint = 'https://www.demo.com';
credential.principalType = 'Anonymous';
credential.protocol = 'NoAuthentication';
credential.oauthToken = newTokenValue;

MetadataService.MetadataPort service = new MetadataService.MetadataPort();
service.SessionHeader = new MetadataService.SessionHeader_element();
service.SessionHeader.sessionId = UserInfo.getSessionId();
service.updateMetadata(
    new List<MetadataService.Metadata> { credential }
);

I checked and this OAuthToken field does support values of 700 characters.

2

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .