You need to sign in to do that
Don't have an account?
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:
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
full + refresh_token for the scopes is a workaround when using full scope and requiring a refresh_token
All Answers
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.
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.
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.
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.
@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?
full + refresh_token for the scopes is a workaround when using full scope and requiring a refresh_token
Cirrius - looks like a bug we'll get cleaned up. dmarchant's workaround is the immediate fix.
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
@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!!
@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?
@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?
@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
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)
{
...
Looks like from your code sample you are passing in xml in the format parameter.
Change it to "urlencoded" and see what happens.
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
@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.
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.
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.
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?
That sounds rather odd. I'd file a support ticker for that.
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
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
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
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
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.
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.