You need to sign in to do that
Don't have an account?

Getting an OAuth token
I am trying to obtain an OAuth token.
I see that there is some Java code on http://www.salesforce.com/us/developer/docs/api_rest/Content/quickstart_oauth.htm, but it is not very useful. Is this a web app? A command line app? What packages are being imported? There are some variables put into the initParams array, but this array is never used as far as I can tell. Can this app be downloaded from somewhere?
I think I got an access token. I was able to get one via curl. I think. It is about 110 characters. Is that normal?
I got it via this:
curl -v -k https://na3.salesforce.com/services/oauth2/token -d "grant_type=password" -d "client_id=COMNSUMER_KEY" -d "client_secret=CONSUMER_SECRET" -d "username=USERNAME" -d "password=PASSWORD"
I saw another post that I would need to get a refresh token because the access tokens expire. How do I get that?
For anyone else looking for an answer to this, to login using the "password" grant type, you must do the following:
If you are successful, something like the following will appear in your response:
If your credentials are incorrect or you did something stupid (like I did when I didn't encode the URL properly), you will see something like the following:
Now you can REST.
Thanks for posting this.
Here is the curl version
curl -d "username=username@company.com&client_secret=123456789&password=pwdgoeshere&grant_type=password&client_id=ReallyLongClientIDGoesHere" -H "Accept: application/json" https://login.salesforce.com/services/oauth2/token
username : your salesforce login name
password : your salesforce password. If you are logging in from a non whitelisted host, you will need to attach your security token
client_secret : the "Consumer Secret" found on the remote access setting
client_id : the "Consumer Key" found on the remote access setting
The REST Getting Started guide at http://wiki.developerforce.com/index.php/Getting_Started_with_the_Force.com_REST_API has a complete working example as a Java servlet. There's also PHP code at http://developer.force.com/cookbook/recipe/interact-with-the-forcecom-rest-api-from-php
Thanks for the link to the tutorial. I am going through it now.
Just so you know: That page has a link to the Apache HttpClient library and it links to the latest version, version 4. The servlet code uses version 3 of ht HttpClient library, which can be found here: http://archive.apache.org/dist/httpcomponents/commons-httpclient/3.0/
How long is the access token good for?
Thanks for the catch! I actually used version 3.1 of the HttpClient library, which is available at a similar location - http://archive.apache.org/dist/httpcomponents/commons-httpclient/ .
I've updated the article.
Cheers,
Pat
The lifetime of an OAuth access token is the same as that of any other session ID - i.e. "Sessions expire automatically after a predetermined length of inactivity, which can be configured in Salesforce by clicking Your Name ➤ Setup ➤ Security Controls. The default is 120 minutes (two hours). If you make an API call, the inactivity timer is reset to zero."
The 'getting started' article doesn't go into any detail on token refresh, but it's covered in the 'digging deeper into OAuth 2.0' article at http://wiki.developerforce.com/index.php/Digging_Deeper_into_OAuth_2.0_on_Force.com
Cheers,
Pat
Do you know if I could run this with two browsers on one machine hitting two different accounts?
Yes - I do this frequently - one account in Firefox, another in Chrome. If you're on the Mac, then Trapdoor is a great tool to help you manage multiple salesforce.com accounts.
Hi,
I'm trying to follow your curl example with the passwprd grant_type, but I get either: "expired access/refresh token" or,
when using a HTTP POST: "grant type not supported".
Any ideas?
Any other examples using curl?
--T.
Can you post the curl command line you're trying to use, and the error you're seeing? Change any sensitive data such as passwords! :-)
Ok, my curl request looks like this:
curl -v --data-urlencode @salesforce.data -H "Accept: application/json" https://test.salesforce.com/services/oauth2/token
and the file: salesforce.data contains (secret stuff removed...):
You need to separate the key/value pairs in the file with '&' rather than <cr> thus:
(with no line break, regardless of how it's actually shown above) and change --data-urlencode to --data.
What's happening is that you're sending
as the body of the post, while the server is expecting
You can see the difference between --data-urlencode and --data if you use --trace - or --trace-ascii -.
Replying to my own post here...
I found out that the problem was that I didn't use the
instance_url I got back with the access token.
I seem to be in the air now, thanks!
--Toby
public class JWT_TokenTest
{
public class JWTClaimSet
{
public string iss {get;set;}
public string scope {get;set;}
public string sub {get;set;}
public string aud {get;set;}
public Long exp {get;set;}
public Long iat {get;set;}
}
//@future (callout=true)
public static void LoginToGoogle()
{
Http http = new Http();
HttpRequest req = new HttpRequest();
HttpResponse res = new HttpResponse();
String JWTHeader = '{"typ":"JWT","alg":"RS256"}';
String Base64EncodedJWTHeader = 'eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiJ9';
Long expires_at = math.roundToLong(DateTime.now().addMinutes(40).getTime() / 1000);
Long issued_at = math.roundToLong(DateTime.now().addSeconds(-2).getTime() / 1000);
JWTClaimSet JWT = new JWTClaimSet();
JWT.iss = '??????????????';
JWT.sub = '??????????????;
JWT.aud = 'https://test.salesforce.com';
JWT.iat = issued_at;
JWT.exp = expires_at;
String strJWTJSON = JSON.Serialize(JWT);
system.debug('Unencoded claimset::'+strJWTJSON);
Blob ClaimsetBlob = Blob.valueOf(strJWTJSON);
String Base64EncodedClaimset = EncodingUtil.base64Encode(ClaimsetBlob);
//Base64EncodedClaimset = PerformPostBase64Encode(Base64EncodedClaimset);
system.debug('Base64 Encoded Claimset::'+Base64EncodedClaimset);
// constructing the base64 encoded string to sign it
string Base64EncodedString = Base64EncodedJWTHeader + '.' + Base64EncodedClaimset;
// Steps to sign the base64Encoded string
String algorithmName = 'RSA';
String key = '????????????????????????????????????';
Blob privateKey = EncodingUtil.base64Decode(key);
Blob input = Blob.valueOf(Base64EncodedString);
//Blob SHA256InputBlob = Crypto.generateDigest('SHA-256',input);
//Blob Blobsign = Crypto.generateDigest('SHA-256',input);
Blob Blobsign = Crypto.sign(algorithmName, input , privateKey);
// The following line is just for debugging and viewing the blob data in signature as string and its not used anywhere
//String signature = EncodingUtil.urlEncode(EncodingUtil.convertToHex(Blobsign),'UTF-8');
//system.debug('Unencoded signature ::'+signature);
String base64EncodedSignature = EncodingUtil.base64Encode(Blobsign);
//base64EncodedSignature = PerformPostBase64Encode(base64EncodedSignature);
system.debug('Base 64 encoded signature ::'+base64EncodedSignature );
system.debug('Encoded assertion : ' + Base64EncodedString+'.'+base64EncodedSignature);
string URLEncodedUTF8GrantType = encodingUtil.urlEncode('urn:ietf:params:oauth:grant-type:jwt-bearer','UTF-8');
string URLEncodedUTF8Assertion = encodingUtil.urlEncode(Base64EncodedString+'.'+base64EncodedSignature,'UTF-8');
system.debug('URLEncodedUTF8GrantType : ' + URLEncodedUTF8GrantType);
system.debug('URLEncodedUTF8Assertion : ' + URLEncodedUTF8Assertion);
//Making the call out
req.setEndpoint('?????????????????????????');
req.setMethod('POST');
req.setHeader('Content-Type','application/x-www-form-urlencoded');
req.setBody('grant_type='+URLEncodedUTF8GrantType+'&assertion='+URLEncodedUTF8Assertion);
res = http.send(req);
system.debug('Response : ' + res.getBody());
}
public static String PerformPostBase64Encode(String s)
{
s = s.Replace('+', '-');
s = s.Replace('/', '_');
s = s.Split('=')[0];
return s;
}
}