我度过了一段可怕的时光......我正在尝试使用coldfusion从salesforce获取令牌,但我仍然坚持以下错误
mergeParams
我试过cfscript
{"error":"invalid_grant","error_description":"authentication failure"}
我已经尝试过cfhttp标签
local.http = new Http(url='https://test.salesforce.com/services/oauth2/token',method='post');
local.http.addParam(type='header',name='content-type', value='application/x-www-form-urlencoded');
local.http.addParam(type='formField',name='grant_type', value='password');
local.http.addParam(type='formField',name='client_id', value='client_id');
local.http.addParam(type='formField',name='client_secret', value='client_password_string');
local.http.addParam(type='formField',name='username', value='user@email.com');
local.http.addParam(type='formField',name='password', value='userspassword');
local.http.addParam(type='formField',name='format', value='json');
local.httpSendResult = local.http.send();
rc.httpResult = httpSendResult.getPrefix();
然而,cUrl在我的本地机器上执行的完全相同的调用完全正常
<cfhttp url="https://test.salesforce.com/services/oauth2/token" method="POST">
<cfhttpparam type="header" name="Content-Type" value="application/x-www-form-urlencoded" />
<cfhttpparam type="formField" name="grant_type" value="password" />
<cfhttpparam type="formField" name="client_id" value="client_id" />
<cfhttpparam type="formField" name="client_secret" value="client_password_string" />
<cfhttpparam type="formField" name="username" value="user@email.com" />
<cfhttpparam type="formField" name="password" value="userspassword" />
</cfhttp>
<cfset rc.result = cfhttp.fileContent />
我确保我的ip范围被列入白名单,我的ip放松设置为放松,allusers可以自我授权,我尝试了不同的用户名和密码参数,我得到的是关于无效拨款的相同错误
非常感谢任何帮助
答案 0 :(得分:1)
我无法评论,所以我必须回答:)但这只是一个建议。使用<cfhttpparam type="formfield">
时,默认情况下,ColdFusion URL会为您编码。 ColdFusion会对字符~
,.
,-
和_
进行编码,但根据RFC 3986规范,它实际上不应该这样做(请参阅https://en.wikipedia.org/wiki/Percent-encoding ),因为他们是无保留的人物。如果您的表单字段包含这些字符(并且我怀疑他们这样做,因为您的示例显示了电子邮件地址),那么编码错误的字符可能是导致身份验证失败的原因。
作为快速测试,您可以将encoded="false"
添加到<cfhttpparam>
代码中,然后使用encodeForUrl()
或urlEncodedFormat()
自行对其值进行编码(具体取决于您的ColdFusion版本) ),然后撤消不正确的编码:
<cfhttpparam type="formField" encoded="false" name="username" value="#replacelist(urlEncodedFormat('user@email.com'), '%2D,%2E,%5F,%7E', '-,.,_,~')#">
答案 1 :(得分:1)
以下是从我为访问salesforce而创建的CFC中提取的一些CFScript代码。 (不会按原样运行,但逻辑就在那里 - 抱歉复制完整的东西的代码太多了。)希望它会有所帮助。
我主要使用与您相同的方法,但您可能想要窃取一些特定设置(字符集,内容类型,接受)。
我伪造了loginCredentials结构中的值,但它们的格式大致相同(与您自己的格式进行比较)。
这对我们来说在Railo上运行良好。也许还要检查它不是SSL问题 - 您是否需要将SSL证书添加到Coldfusion中以便它可以与Salesforce通信?
variables.sfAuthDomain = "https://login.salesforce.com";
variables.authServiceURL = variables.sfAuthDomain & "/services/oauth2/token";
variables.accessToken = "xxxxx" // The access token returned by SF, used on future logins
variables.loginCredentials = {
"grant_type": "password",
"client_id": "3MVG9Fkjshdkfjvshd ckjfhjkch.blkjlkjlkjkljl.wkjhgkjhkjhds.mVk84TRzhm_pXxK6_786786",
"client_secret": "3887687686868668727",
"username": "huge.duck@monkey.com.icom.icomqa",
"password": "Bungerloo!PPkjhj324ij45bQGyymmd"
};
/**
* MAKE SERVICE CALL
* Makes HTTP service call
**/
public Struct function makeServiceCall(String serviceUrl, String method="GET", Boolean sfAuth=true, Struct headers={}, Struct formFields) {
var httpService = new http(); // create new http service
var httpResponse = {};
var fieldName = "";
var bodyData = "";
/* set attributes using implicit setters */
httpService.setMethod(arguments.method);
httpService.setCharset("utf-8");
httpService.setUrl(Trim(arguments.serviceURL));
httpService.setTimeOut(variables.timeoutValue);
/* add httpparams using addParam() */
for(fieldName in arguments.headers) {
httpService.addParam(type="header", name="#fieldName#", value="#arguments.headers[fieldName]#");
}
if(arguments.sfAuth){
httpService.addParam(type="header", name="Authorization", value="OAuth #variables.accessToken#");
}
if(StructKeyExists(arguments, "formFields")) {
loop collection="#arguments.formFields#" item="fieldName" {
bodyData = ListAppend(bodyData, "#fieldName#=#formFields[fieldName]#", "&");
}
}
if(bodyData is not "") {
httpService.addParam(type="body", name="post", encoded="no", value="#bodyData#");
}
/* make the http call to the URL using send() */
httpResponse = httpService.send().getPrefix();
//dump(httpResponse, false, "modern", "", 500, "httpResponse");
return httpResponse;
}
httpResponse = makeServiceCall(
serviceUrl = serviceURL,
method = "POST",
sfAuth = false,
headers = {
"Content-Type": "application/x-www-form-urlencoded",
"accept": "text/json"
},
formFields = loginCredentials
);
答案 2 :(得分:0)
结束更改我的coldfusion服务器以使用TLS 1.2,因为不推荐使用TLS 1.0供salesforce使用。希望我的回答和这篇文章中给出的有用答案可以帮助别人
答案 3 :(得分:0)
您的密码表单字段值仅包含密码,因此将显示这种错误:
({"error":"invalid_grant","error_description":"authentication failure"})
。
必须包含(密码和安全令牌)。
<cfhttpparam type="formField" name="password" value="#arguments.password##arguments.Security_token#"/>