I am trying to integrate netsuite modules in iOS application. I am not able generate proper oauth signature for the header. I have tried using 'OAuthSwift' library for this purpose, but I have no proper idea on how to add the headers like oauth_nonce, oauth_signature. I have searched many websites and checked stackoverflow references but found none for my requirement.
As per the comment I followed the java code posted [https://stackoverflow.com/questions/51286409/netsuite-token-based-authentication].
Here is the code I have worked on. The response I got is INVALID_LOGIN_ATTEMPT. My guess is, maybe the OAUTH_Signature is wrong. Please help me.
import UIKit import CommonCrypto class ViewController: UIViewController { var OAuth = ""; override func viewDidLoad() { super.viewDidLoad() var oauth_val = mediate(); let url = URL(string: "https://5250636-sb2.restlets.api.netsuite.com/app/site/hosting/restlet.nl?script=2162&deploy=1") guard let requestUrl = url else { fatalError() } // Create URL Request var request = URLRequest(url: requestUrl) // Specify HTTP Method to use request.httpMethod = "GET" //http header request.setValue("application/json", forHTTPHeaderField: "Accept") request.setValue("application/json", forHTTPHeaderField: "Content-Type") request.setValue(oauth_val, forHTTPHeaderField: "Authorization") // Send HTTP Request let task = URLSession.shared.dataTask(with: request) { (data, response, error) in // Check if Error took place if let error = error { print("Error took place \(error)") return } // Read HTTP Response Status code if let response = response as? HTTPURLResponse { print("Response HTTP Status code: \(response.statusCode)") } // Convert HTTP Response Data to a simple String if let data = data, let dataString = String(data: data, encoding: .utf8) { print("Response data string:\n \(dataString)") } } task.resume() } func randomString(length: Int) -> String { let letters = "2312312312312sadadadadNKSNSKMSLMXSX" return String((0..<length).map{ _ in letters.randomElement()! }) } func computeSignature(baseString: String, keyString: String) -> String { let hmacResult:String = keyString.hmac(algorithm: HMACAlgorithm.SHA1, key: keyString) return hmacResult } func mediate()-> String { let base_url = "baseurl" let http_method = "GET" var token_id = "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" var token_secret = "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" var consumerkey = "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" var consumer_secret = "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" var SIGNATURE_METHOD = "HMAC-SHA1" var OAUTH_NONCE = randomString(length: 20) var TIME_STAMP = String(Date().toMillis()) var OAUTH_VERSION = "1.0" var SCRIPT_DEPLOYMENT_ID = "xxx" var SCRIPT_ID = "xxx" var REALM = "xxxxx" var encdata = "" encdata = encdata + "deploy=" + SCRIPT_DEPLOYMENT_ID + "&" encdata = encdata + "oauth_consumer_key=" + consumerkey + "&" encdata = encdata + "oauth_nonce=" + OAUTH_NONCE + "&" encdata = encdata + "oauth_signature_method=" + SIGNATURE_METHOD + "&" encdata = encdata + "oauth_timestamp=" + TIME_STAMP + "&" encdata = encdata + "oauth_token=" + token_id + "&" encdata = encdata + "oauth_version=" + OAUTH_VERSION + "&" encdata = encdata + "script=" + SCRIPT_ID let encodeData = encdata.urlEncoded()! let completeData = http_method + "&" + base_url.urlEncoded()! + "&" + encodeData var key = ""; key = consumer_secret.urlEncoded()! + "&" + token_secret.urlEncoded()! var signature = computeSignature(baseString: completeData, keyString: key) OAuth = "OAuth realm=\"" + REALM + "\","; OAuth = OAuth + "oauth_consumer_key=\"" + consumerkey + "\","; OAuth = OAuth + "oauth_token=\"" + token_id + "\","; OAuth = OAuth + "oauth_signature_method=\"HMAC-SHA1\","; OAuth = OAuth + "oauth_timestamp=\"" + TIME_STAMP + "\","; OAuth = OAuth + "oauth_nonce=\"" + OAUTH_NONCE + "\","; OAuth = OAuth + "oauth_version=\"" + "1.0" + "\","; OAuth = OAuth + "oauth_signature=\"" + signature + "\""; return OAuth; } func printCharactersInSet(set: NSCharacterSet) { var characters = "" let iSet = set.inverted for i: UInt32 in 32..<127 { let c = Character(UnicodeScalar(UInt32(i))!) if iSet.hasMember(inPlane: UInt8(i)) { characters = characters + String(c) } } print("characters not in set: \'\(characters)\'") } } enum HMACAlgorithm { case MD5, SHA1, SHA224, SHA256, SHA384, SHA512 func toCCHmacAlgorithm() -> CCHmacAlgorithm { var result: Int = 0 switch self { case .MD5: result = kCCHmacAlgMD5 case .SHA1: result = kCCHmacAlgSHA1 case .SHA224: result = kCCHmacAlgSHA224 case .SHA256: result = kCCHmacAlgSHA256 case .SHA384: result = kCCHmacAlgSHA384 case .SHA512: result = kCCHmacAlgSHA512 } return CCHmacAlgorithm(result) } func digestLength() -> Int { var result: CInt = 0 switch self { case .MD5: result = CC_MD5_DIGEST_LENGTH case .SHA1: result = CC_SHA1_DIGEST_LENGTH case .SHA224: result = CC_SHA224_DIGEST_LENGTH case .SHA256: result = CC_SHA256_DIGEST_LENGTH case .SHA384: result = CC_SHA384_DIGEST_LENGTH case .SHA512: result = CC_SHA512_DIGEST_LENGTH } return Int(result) } } extension String { func hmac(algorithm: HMACAlgorithm, key: String) -> String { let cKey = key.cString(using: String.Encoding.utf8) let cData = self.cString(using: String.Encoding.utf8) var result = [CUnsignedChar](repeating: 0, count: Int(algorithm.digestLength())) CCHmac(algorithm.toCCHmacAlgorithm(), cKey!, strlen(cKey!), cData!, strlen(cData!), &result) let hmacData:NSData = NSData(bytes: result, length: (Int(algorithm.digestLength()))) let hmacBase64 = hmacData.base64EncodedString(options: NSData.Base64EncodingOptions.lineLength76Characters)// Encoding76CharacterLineLength) return String(hmacBase64) } var urlEncoded: String { let customAllowedSet = CharacterSet(charactersIn: "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789-._~") return self.addingPercentEncoding(withAllowedCharacters: customAllowedSet)! } var urlQueryEncoded: String? { return self.addingPercentEncoding(withAllowedCharacters: CharacterSet.urlQueryAllowed) } func substring(to offset: String.IndexDistance) -> String { let to = self.index(self.startIndex, offsetBy: offset) return String(self[..<to]) } } extension Dictionary { var urlEncodedQuery: String { var parts = [String]() for (key, value) in self { let keyString = "\(key)".urlEncoded let valueString = "\(value)".urlEncoded let query = "\(keyString)=\(valueString)" parts.append(query) } return parts.joined(separator: "&") } } extension Date { func toMillis() -> Int64! { return Int64(self.timeIntervalSince1970 * 1000) } } extension StringProtocol { var containsLetters: Bool { contains { $0.isLetter } } } public extension CharacterSet { static let urlQueryParameterAllowed = CharacterSet.urlQueryAllowed.subtracting(CharacterSet(charactersIn: "&?")) static let urlQueryDenied = CharacterSet.urlQueryAllowed.inverted() static let urlQueryKeyValueDenied = CharacterSet.urlQueryParameterAllowed.inverted() static let urlPathDenied = CharacterSet.urlPathAllowed.inverted() static let urlFragmentDenied = CharacterSet.urlFragmentAllowed.inverted() static let urlHostDenied = CharacterSet.urlHostAllowed.inverted() static let urlDenied = CharacterSet.urlQueryDenied .union(.urlQueryKeyValueDenied) .union(.urlPathDenied) .union(.urlFragmentDenied) .union(.urlHostDenied) func inverted() -> CharacterSet { var copy = self copy.invert() return copy } } public extension String { func urlEncoded(denying deniedCharacters: CharacterSet = .urlDenied) -> String? { return addingPercentEncoding(withAllowedCharacters: deniedCharacters.inverted()) } } https://stackoverflow.com/questions/66113586/netsuite-oauth-1-0-authentication-from-swift-ios February 09, 2021 at 01:42PM
没有评论:
发表评论