function readOnly(count){ }
Starting November 20, the site will be set to read-only. On December 4, 2023,
forum discussions will move to the Trailblazer Community.
+ Start a Discussion
cirrusinsightcirrusinsight 

oauth authorization no longer returning refresh token (HELP!)

I have an application using oAuth for authorization. It's been working fine for months. Over the weekend, issues started happening and after digging into it, it appears that while the authorization is successful (response 200 with valid JSON object returned), we're no longer receiving a refresh token after authorization.

 

Here is the oAuth request/response:

REQUEST:
https://login.salesforce.com/services/oauth2/token?grant_type=authorization_code&client_id=[my_app_client_id]&client_secret=[my_app_client_secret]&redirect_uri=[my_app_redirect_url]&code=[the_auth_code_we_receive_during_authorization]

 

RESPONSE:

{

"id":"https://login.salesforce.com/id/00D30000000AAAAAAA/0053000000KKKKKK",
"issued_at":"1328965006241",
"scope":"full",
"instance_url":"https://[my_org].my.salesforce.com",
"signature":"J/YL4wUXF[stuff]ielR+GLrcBuDz/kHOJs3nKNs=",
"access_token":"00D30000000AAAA!AREAQHAQpw[stuff]ABL50MBOQVPsN.TTnrrvN2gAGNsrJHhK3ehSQvYU[stuff]MfqreLBp3eDXMnCNdJRl3"
}

 

This request is supposed to return a request_token parameter with the JSON response -- and it *always* has in the past. Docs here: http://wiki.developerforce.com/page/Digging_Deeper_into_OAuth_2.0_on_Force.com

Best Answer chosen by Admin (Salesforce Developers) 
dmarchantdmarchant

full + refresh_token for the scopes is a workaround when using full scope and requiring a refresh_token

All Answers

Navatar_DbSupNavatar_DbSup

 

Hi,
Inorder to get the refresh token you need to set grant_type=refresh_token.

 

for example set the http end point to send request for refresh_token as done below

 


httprequest hreq=new httprequest();
string refresh_url='https://login.salesforce.com/services/oauth2/token?grant_type=refresh_token&client_id='+consumer_key+'&client_secret='+client_secret+'&refresh_token='+refresh_token;
system.debug('_________________refresh_url______________'+refresh_url);
hreq.Setendpoint(refresh_url);
hreq.setmethod('POST');
hreq.setHeader('Accept', 'application/xml;charset=UTF-8');
hreq.setHeader('Host','ap1.salesforce.com');
http htp=new http();
httpResponse res=htp.send(hreq);

System.debug('__________________________FutureRefreshToken_ID_______________________________' +res.getBody());
readXMLResponseOfFutureAccessToken(res.getBody());


For more detail follow the below link:
http://wiki.developerforce.com/page/Digging_Deeper_into_OAuth_2.0_on_Force.com

 

Did this answer your question? If not, let me know what didn't work, or if so, please mark it solved. 

cirrusinsightcirrusinsight

Hi. Thanks for your reply.

 

Actually, I don't think that's true.

 

See the docs here: http://wiki.developerforce.com/page/Digging_Deeper_into_OAuth_2.0_on_Force.com#Obtaining_an_Access_Token_in_a_Web_Application_.28Web_Server_Flow.29

 

Also, we've been using "authorization_code" since the beginning and this only stopped working over the weekend... ?

 

Nonetheless, I'll try it out.

cirrusinsightcirrusinsight

Yes, we must use authorization_code at this stage of the oauth process.

 

Let me clarify -- 

 

you pass in grant_type=refresh_token when you already have a refresh token and you're requesting a new access token.

 

In this case, we're requesting authorization for the first time -- and a refresh token should be included in this response.

dmarchantdmarchant

 

During the authorization step of OAuth, update your request to pass scope=full%20refresh_token

This will allow you to get the refresh token during the token exchange process.

Pat PattersonPat Patterson

@Navatar_DbSup: cirrusinsight is correct - grant_type=refresh_token is for passing a refresh token to get a new access token.

 

I just tried an external Ruby app and it gets a refresh_token, just as it used to, no scope required.

 

@cirrusinsight - does dmarchant's suggestion work for you?

 

@dmarchant - did something change here? Is scope=full%20refresh_token a workaround?

dmarchantdmarchant

full + refresh_token for the scopes is a workaround when using full scope and requiring a refresh_token

This was selected as the best answer
chuckmortimorechuckmortimore

Cirrius - looks like a bug we'll get cleaned up.   dmarchant's workaround is the immediate fix.

 

Steve BrownSteve Brown

I don't know if this helps, but I noticed that my refresh token flow stopped working yesterday as well.

 

At first, the issue surfaced itself by succesfully returning JSON responses with a new access token. However, I was requesting a url-encoeed response. This worked for several months until yesterday.

 

This morning, I received the "expired access/refresh token error", so I deleted the token from my DB and did the dance to get a new one. That worked fine and I could access SF data successfully. But when I make the call to refresh the access token, I consistently get the "expired access/refresh token error" response.

 

Is anybody else seeing this?

 

-Steve

cirrusinsightcirrusinsight

@dmarchant: THANK YOU. This workaround worked. How long ago did you implement that, and why? "full" had ALWAYS worked for me before.

 

@chuckmortimer: Good to know. I opened up case #07025972

 

 

ALL: Thank you very much!!

dmarchantdmarchant

@cirrusinsight

Since the introduction of scopes this is how the functionality worked, in Winter '11 +

 

@Steve Brown

This just started breaking this weekend for you?

 

Anyone else see the issue Steve is having?

cirrusinsightcirrusinsight

@dmarchant

I can say that without a doubt this was working until Friday/Saturday.

 

@steve Brown

This issue first manifested itself with that error *for me*. What we were doing was assuming the refresh token was included in the response but then using NULL as the refresh token and getting that error back. Maybe something similar for you?

Steve BrownSteve Brown

@cirrusinsight

In my case, I have always received the refresh token in my grant response, so no issue there for me.  But yesterday the problems started when I would receive the refreshed access token responses in JSON, whereas I have always requested them be url-encoded. Today, I don't even get JSON anymore. I just get the "invalid_grant"error with the "expired access/refresh token" message.

 

@dmarchant

This just started yesterday afternoon for me. Are you seeing it too?

 

-Steve

Steve BrownSteve Brown

Update:

I figured out why I was getting the grant type error. I wasn't un-protecting the refresh token in my test code that is trying to refresh the token. So now that I have that fixed, I can get a response from SF with a new access token.

However, all responses are still in JSON, regardless of which response format I request. The endpoint seems to no-longer honor the HTTP Accept header, nor the format parameter.

If I use the following code, I get back JSON even when I ask for URL-encoded or XML:

HttpWebRequest webRequest = null;
HttpWebResponse webResponse = null;
try
{
    webRequest = (HttpWebRequest)WebRequest.Create(SALESFORCE_REFRESH_TOKEN_URL);
    webRequest.Method = "POST";
    webRequest.ContentType = "application/x-www-form-urlencoded";
    //webRequest.Accept = "application/x-www-form-urlencoded";
    using (StreamWriter writer = new StreamWriter(webRequest.GetRequestStream()))
    {
        System.Text.StringBuilder sb = new System.Text.StringBuilder();
        sb.AppendFormat("grant_type={0}", HttpUtility.UrlEncode("refresh_token"));
        sb.AppendFormat("&refresh_token={0}", HttpUtility.UrlEncode(token.RefreshToken));
        sb.AppendFormat("&client_id={0}", HttpUtility.UrlEncode(token.ConsumerKey));
        sb.AppendFormat("&format={0}", HttpUtility.UrlEncode("xml"));

        writer.WriteLine(sb.ToString());
    }

    webResponse = (HttpWebResponse) webRequest.GetResponse();
    using (StreamReader reader = new StreamReader(webResponse.GetResponseStream()))
    {
        String responseBody = reader.ReadToEnd();
        ...
    }
catch (WebException err)
{
    ...

dmarchantdmarchant

Looks like from your code sample you are passing in xml in the format parameter.

Change it to "urlencoded" and see what happens.

Steve BrownSteve Brown

The original value was urlencoded. I tried XML as well to see if it would return XML. That's what you see in the sample. Regardless of what I pass in, I get JSON back.

 

To insulate my code, I've decided to not assume I'll get back the response format I requested, and I will sniff the response and use the appropriate parsing technique.

 

-Steve

javamatejavamate

@chuckmortimore - Any idea when the bug will be fixed?  This was working for my application until recently as well (that is, we received the refresh_token with the initial authorization_code request with no scope per the documentation, but now we get no refresh_token).

 

If the fix is going to take a while, will the suggested workaround continue to work after the fix is in place?  I'd rather not have to implement this workaround if I can avoid it as it requires a production update of our application.

ASP@shivASP@shiv

I am trying to navigate to this end point but get an error :URL no longer exists.

https://login.salesforce.com/services/oauth2/authorize?response_type=code&client_id="my clientID"&redirect_uri ="my Uri"

 

Has the authorisation end point changed ,or is there something else I am missing out.

Please help.

JustpissedOFFJustpissedOFF

Hi All,

 

This is still a issue?

 

Can someone please direct me to the solution for this issue as the solution provided here is not working for REST API OAuth.

 

Below is the response returned after making the authorization_code grant type request.

 

Passing the scope parameter results in a "invalid_request" : "scope parameter not supported" error.

 

publicstring id {get;set;}
publicstring issued_at {get;set;}
publicstring scope {get;set;}
publicstring instance_url {get;set;}
publicstring signature {get;set;}
publicstring access_token {get;set;}
DanielDDanielD

I have the same problem when using the iOS SDK, i've set an https URL in salesforce setting, but when i use the https in my code, i cant add refresh_token to the scope, if i do so, the API will complain that the scope not available. Then I changed https to http, this time i can add refresh_token to the scope, but when OAuth returns, there is no refresh_token, but only access_token...

anyone got any idea about this issue?

chuckmortimorechuckmortimore

That sounds rather odd.   I'd file a support ticker for that.

Rakesh ERakesh E
Hi dmarchant,

i am also facing same issue. not getting refresh token in the response. when i add this parameter (scope=full%20refresh_token) in request body
i am getting an error saying that "Scope parameter not supported"
could you please tell me what could be the solution for this

thank you

Regards,
Rakesh
Rakesh ERakesh E

Hi cirrusinsight ,

i am also facing same issue. not getting refresh token in the response. when i add this parameter (scope=full%20refresh_token) in request body
i am getting an error saying that "Scope parameter not supported"
could you please tell me what could be the solution for this

thank you

Regards,
Rakesh

Rakesh ERakesh E

Hi All,

 

i am generating OAuth token using "Username-Password" flow. in this type we specify "grant_type=password". in the response i am not getting "refresh_token" in the response.

 

is there any way to get "refresh_token" using grant_type as password. any suggestions will be greatful. 

 

the basic requirement for us is to connect between two salesforce orgs. (from one salesforce org we want to get the OAuth token and refresh token of other salesforce org , in which we are unable to use "Redirect URI" method to get the autorization code)

 

Regards,

Rakesh

tushar dhawantushar dhawan
As per Salesforce Doc to get refersh token for User Name - Agent Flow below mention points are required:

The redirect URI has a custom (non-https) scheme
The redirect URL is exactly https://login.salesforce.com/services/oauth2/success for production or on Force.com Sandbox https://test.salesforce.com/services/oauth2/success.
Try using this to get Refresh_token
Danny SmartDanny Smart
I recently had the issue of no refresh token in the authorization response, coupled with "Scope parameter not supported" when using the Web Server authorization flow.

Turns out all scopes are set on your Connected App and if you don't have the "refresh token / offline access" scope, you won't receive a refresh token in the authorization response, which kinda makes sense but it would have been nice if SF documented that fact somewhere.

You can change the scopes your App has access to by going to Setup > Create > App and Editing the Connected App you are using.
Naga BalaNaga Bala
Hi All,

I am trying to connect two salesforce orgs using OAuth .But I am confused how to send the POST requested after redirecting VF page with Authorize URL.

Below is the URL I am using to authorize :https://login.salesforce.com/services/oauth2/authorize.

Any help is appreciated.
Richard TelfordRichard Telford
Danny Smart's answer solved the problem for me.
Laxmish JoshiLaxmish Joshi
@Danny Smart, Thanks a ton !! Issue resolved
Juan CaceresJuan Caceres
Danny Smart's answer worked for me too! Thanks @Danny Smart.