Reputation: 41
I'm currently working on a project that involves creating cases in Salesforce using the Salesforce API. However, I'm encountering an authentication error that I can't seem to resolve, despite checking all the credentials thoroughly.
Issue: When attempting to create a case in Salesforce using the API, I'm receiving the following error:
css Copy code Error: Response data: { error: 'invalid_grant', error_description: 'authentication failure' } Steps Taken:
I've verified that the Salesforce username, password, security token, consumer key, and consumer secret are all correctly configured in my environment variables.
I've ensured that my Salesforce account has API access enabled.
I've added the server's IP address to the trusted IP ranges in Salesforce.
I've double-checked the settings of my connected app in Salesforce to ensure correct OAuth scopes and callback URL.
I'm URL encoding the username and password in the authentication request.
I've added detailed logging to my code to capture the request and response during the authentication process.
The API version I'm using is v58.0.
I'm using the standard endpoint /services/oauth2/token to obtain the access token.
I've confirmed that I'm not trying to use an expired access token.
The server's clock is synchronized correctly.
I'm aware of Salesforce's API rate limits and don't believe I'm hitting them.
I've checked for network-related issues that might be affecting communication with Salesforce's servers.
Despite these efforts, I'm still facing an authentication error. I suspect I might be missing something or not considering a crucial aspect of the authentication process.
const axios = require('axios');
const dotenv = require('dotenv');
dotenv.config();
const SALESFORCE_USERNAME = process.env.SALESFORCE_USERNAME;
const SALESFORCE_PASSWORD = process.env.SALESFORCE_PASSWORD;
const SALESFORCE_SECURITY_TOKEN = process.env.SALESFORCE_SECURITY_TOKEN;
const SALESFORCE_CONSUMER_KEY = process.env.SALESFORCE_CONSUMER_KEY;
const SALESFORCE_CONSUMER_SECRET = process.env.SALESFORCE_CONSUMER_SECRET;
const SALESFORCE_INSTANCE_URL = 'https://platform-app-826.my.salesforce.com';
const API_VERSION = 'v58.0';
async function createSalesforceCase() {
try {
const authRequestData = new URLSearchParams({
grant_type: 'password',
client_id: SALESFORCE_CONSUMER_KEY,
client_secret: SALESFORCE_CONSUMER_SECRET,
username: encodeURIComponent(SALESFORCE_USERNAME),
password: encodeURIComponent(`${SALESFORCE_PASSWORD}${SALESFORCE_SECURITY_TOKEN}`)
});
const authResponse = await axios.post(
`${SALESFORCE_INSTANCE_URL}/services/oauth2/token`,
authRequestData.toString(), {
headers: {
'Content-Type': 'application/x-www-form-urlencoded'
}
}
);
const accessToken = authResponse.data.access_token;
console.log('Salesforce Authentication Successful');
const customerPhoneNumber = '+1234567890';
const customerQuery = 'This is a test query from the customer.';
const caseData = {
Subject: `Amazon Connect case from ${customerPhoneNumber}`,
Description: customerQuery,
Priority: 'Medium',
Origin: 'Phone',
Comments: `Rider Phone number is ${customerPhoneNumber}`
};
try {
if (!accessToken) {
throw new Error('Access token not available.');
}
const response = await axios.post(
`${SALESFORCE_INSTANCE_URL}/services/data/${API_VERSION}/sobjects/Case`,
caseData, {
headers: {
Authorization: `Bearer ${accessToken}`,
'Content-Type': 'application/json'
}
}
);
console.log('Case ID:', response.data.id);
} catch (err) {
console.error('Error creating case:', err.message);
}
} catch (err) {
console.error('Error during authentication:', err.message);
if (err.response) {
console.error('Response data:', err.response.data);
}
}
}
createSalesforceCase().catch(err => {
console.error('Unhandled error:', err.message);
});
Upvotes: 1
Views: 220
Reputation: 86
You don't need to encodeURIComponent the username and password.
const authRequestData = new URLSearchParams({
grant_type: 'password',
client_id: SALESFORCE_CONSUMER_KEY,
client_secret: SALESFORCE_CONSUMER_SECRET,
username: SALESFORCE_USERNAME, // <-- here
password: `${SALESFORCE_PASSWORD}` // <-- here in my case, I didn't need a security token
});
When I print authRequestData
this is how it looks like your request before removing encodeURIComponent
authRequestData URLSearchParams {
'grant_type' => 'password',
'client_id' => 'myclienId',
'client_secret' => 'my-secret',
'username' => 'XXXX%40domain-mail.com', // <-- as you can see converts the @ for encode URI %40
'password' => 'my-password' }
I really recommend using jsforce
npm package, which simplifies the job.
Reference for login using jsforce
https://jsforce.github.io/document/#username-and-password-login
Again, hope this helps you.
Upvotes: 0