基于Token的NetSuite认证请求返回INVALID_LOGIN_ATTEMPT错误排查
NetSuite Token身份验证请求返回INVALID_LOGIN_ATTEMPT的问题排查
以下是用于NetSuite基于令牌的身份验证(TBA)的Apex代码:
String nonce = String.valueOf(Crypto.getRandomLong()); String tnow = String.valueOf(DateTime.now().getTime()/1000); String baseString = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789&'+nonce+'&'+tnow+''; system.debug('baseString'+ baseString); String consumerSecret = 'xxxxxxxxxxxxxxxxxxxxxxxxxxxc6c7691081bcb9b9eec6'; String tokenSecret = 'xxxxxxxxxxxxxxxxxxxxxxx91081bcb9b9eec6'; String signingkey = consumerSecret+'&'+tokenSecret; system.debug('signingkey'+ signingkey); Blob sig = Crypto.generateMac('HMAC-SHA256', Blob.valueOf(baseString), Blob.valueOf(signingkey)); String signature = EncodingUtil.urlEncode(EncodingUtil.base64encode(sig), 'UTF-8'); system.debug('sig'+ sig); System.debug('Signature: '+signature); Http http = new Http(); HttpRequest request = new HttpRequest(); String AuthString = 'OAuth realm="xxxxxxxx_SB1",oauth_consumer_key="xxxxxxxxxxxxxxd68a2d175b93bf41be264c1fd",oauth_token="xxxxxxxxxxxxxxx439146c971fb0398c5db3f417", oauth_signature_method="HMAC-SHA256", oauth_timestamp="'+tnow+'", oauth_nonce="'+nonce+'", oauth_version="1.0", oauth_signature="'+signature+'"'; System.debug('Authorization: '+AuthString); request.setEndpoint('https://xxxxxxxxxx-SB1.suitetalk.api.netsuite.com/services/rest/record/v1/customer/956'); request.setMethod('GET'); request.setHeader('Accept','/'); request.setHeader('Authorization', AuthString); request.setHeader('Content-Type', 'text/plain'); request.setHeader('prefer', 'transient'); HttpResponse response = http.send(request); System.debug(response.getBody());
调用后返回错误:
"{ error : { code :"INVALID_LOGIN_ATTEMPT", message :"Invalid login attempt."}} ".
问题分析与修正方案
1. 签名基字符串(Base String)构造完全错误
OAuth 1.0a要求签名基字符串必须严格遵循HTTP_METHOD&ENCODED_REQUEST_URL&ENCODED_PARAMETER_STRING的格式,你当前的baseString开头是无意义的随机字符,完全不符合规范。
正确构造步骤:
// 编码请求URL String encodedUrl = EncodingUtil.urlEncode('https://xxxxxxxxxx-SB1.suitetalk.api.netsuite.com/services/rest/record/v1/customer/956', 'UTF-8'); // 整理所有OAuth参数并按字典序排序 Map<String, String> oauthParams = new Map<String, String>{ 'oauth_consumer_key' => 'xxxxxxxxxxxxxxd68a2d175b93bf41be264c1fd', 'oauth_nonce' => nonce, 'oauth_signature_method' => 'HMAC-SHA256', 'oauth_timestamp' => tnow, 'oauth_token' => 'xxxxxxxxxxxxxxx439146c971fb0398c5db3f417', 'oauth_version' => '1.0' }; // 拼接并编码参数键值对 List<String> paramPairs = new List<String>(); for (String key : oauthParams.keySet().sort()) { paramPairs.add(EncodingUtil.urlEncode(key, 'UTF-8') + '=' + EncodingUtil.urlEncode(oauthParams.get(key), 'UTF-8')); } String encodedParams = String.join(paramPairs, '&'); // 生成合法的签名基字符串 String baseString = 'GET' + '&' + encodedUrl + '&' + encodedParams;
2. 签名密钥(Signing Key)错误使用HTML转义
签名密钥只需直接拼接consumerSecret + '&' + tokenSecret,不需要用&进行HTML转义:
String signingkey = consumerSecret + '&' + tokenSecret;
3. Authorization头格式错误
- 参数间存在多余空格:OAuth参数必须用逗号直接分隔,不能加空格(比如
oauth_token后的空格要删除) - 引号转义错误:应直接使用双引号,而非
"(Apex中用单引号包裹字符串时,内部双引号可直接书写)
修正后的Authorization头:
String AuthString = 'OAuth realm="xxxxxxxx_SB1",oauth_consumer_key="xxxxxxxxxxxxxxd68a2d175b93bf41be264c1fd",oauth_token="xxxxxxxxxxxxxxx439146c971fb0398c5db3f417",oauth_signature_method="HMAC-SHA256",oauth_timestamp="' + tnow + '",oauth_nonce="' + nonce + '",oauth_version="1.0",oauth_signature="' + signature + '"';
4. Accept头设置不合法
Accept '/'格式错误,应改为标准值,比如接受所有类型的*/*:
request.setHeader('Accept', '*/*');
内容的提问来源于stack exchange,提问作者Eline
相关产品推荐
相关产品推荐

