How to set pass api key within NSURLRequest in iOS? - ios

as of now I have it like so:
NSURLRequest *Request = [NSURLRequest requestWithURL:[NSURL URLWithString: reqURLStr]];
NSURLResponse *resp = nil;
NSError *error = nil;
NSData *response = [NSURLConnection sendSynchronousRequest: Request returningResponse: &resp error: &error];
NSString *responseString = [[NSString alloc] initWithData:response encoding:NSUTF8StringEncoding];
return responseString;
and I call it like so:
NSString *stripeCustomerRequestURL = [NSString stringWithFormat:#"https://api.stripe.com/v1/customers/%#",stripeCustomerId];
// NSString for the return of the tax in decimal form
NSString *customerInformation = [self retrieveStripeCustomer:stripeCustomerRequestURL];
I am getting this error which I know I need to pass the api key but how can I?
{
"error": {
"type": "invalid_request_error",
"message": "You did not provide an API key. You need to provide your API key in the Authorization header, using Bearer auth (e.g. 'Authorization: Bearer YOUR_SECRET_KEY'). See https://stripe.com/docs/api#authentication for details, or we can help at https://support.stripe.com/."
}
}

It is not considered secure to be using your Stripe Secret API key from code that runs on a client device (iOS / Android apps, desktop apps, etc). As soon as you include your API key in a shipped binary, you can assume someone will inspect your binary and be able to extract the strings from it, including your API key thus compromising it.
Your API key should only be used on a server that you control. Your iOS app can call endpoints on your server and in turn your server will call out to Stripe.

Related

Read Data/Response/Body of redirected NSURLDataTask

I am currently trying to access a webpage where the user can login using their credentials, after entering their user and password - if correct it will redirect to a new url. This new url loads a webpage with a single string which I intend to use.
However, how am I able to check the contents of the redirected url? At the moment I am only able to check the Response/Data/Contents of the initial page loaded by the following method;
NSURLSessionConfiguration *configuration = [NSURLSessionConfiguration defaultSessionConfiguration];
casSession = [NSURLSession sessionWithConfiguration:configuration delegate:self delegateQueue:nil];
NSString *urlAddress = #"https://originalurl.com";
NSURL *httpUrl = [NSURL URLWithString:urlAddress];
NSURLRequest *requestObj = [NSURLRequest requestWithURL:httpUrl];
[loginPage loadRequest:requestObj];
NSURLSessionDataTask *redirect = [casSession dataTaskWithURL:httpUrl completionHandler:^(NSData * _Nullable data, NSURLResponse * _Nullable response, NSError * _Nullable error) {
NSString *newURL = [NSString stringWithFormat: #"%#", response.URL];
if ([newURL containsString:#"ticket=ST"]) {
NSString * registrationID = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
NSLog(#"REGISTRATION: %#", registrationID);
if (registrationID != nil) {
dispatch_async(dispatch_get_main_queue(), ^{
loginPage.hidden = YES;
});
}
} else {
NSLog(#"No ticket recieved");
}
}];
[redirect resume];
I'm not sure which delegate to use, in order to actively check every time a redirection happens and then obtain the contents of the new url?
Thanks.
You’re looking at this the wrong way. You should query the user for the login info directly and insert that into a single NSURLDataTask. Then the data task should query the server with the login info, and return some data.
This all happens with APIs (in a broad manner of speaking) where you will not present HTML contents to the user, but instead some sort of encoded data that is returned.
So for example, once you have a task defined from a URL or URLRequest, and you begin the task, you then use the completion handler to verify the returned data and/or error. If here, you may decode the returned data as a NSString, and then convert the JSON to objects, such as a user’s profile’s data (name, age, email, ...)
I did not go into detail in this answer because it is a very very broad topic, with many use cases. Look up some tutorials on NSURLDataTasks or consuming APIs from Swift and/or Objective-C.

HTTP post w/ JSON to rails server from iOS

I have succeeded in making a post using a HTTP Client by setting the content type as application/json and this json code:
{
"order": {
"name": "Tia Carter",
"location": "Corams",
"phone_number": "707",
"food": "Bobcat Burger"
}
}
The code works perfect and the order is registered in the database. I am trying to work this into my iOS app but keep getting syntax errors regarding the colons in the json. This is the objective-c code:
NSURL *nsURL = [[NSURL alloc] initWithString:#"http://0.0.0.0:3000/orders.json"];
NSMutableURLRequest *nsMutableURLRequest = [[NSMutableURLRequest alloc] initWithURL:nsURL];
// Set the request's content type to application/x-www-form-urlencoded
[nsMutableURLRequest setValue:#"application/json" forHTTPHeaderField:#"Content-Type"];
// Set HTTP method to POST
[nsMutableURLRequest setHTTPMethod:#"POST"];
// Set up the parameters to send.
NSString *paramDataString = [NSString stringWithFormat:#
"{ "order": {"%#:" ="%#","%#:"="%#","%#:"="%#","%#:"="%#"}}", #"name", _name.text, #"location", _location.text, #"phone_number", _phoneNumber.text, #"food", _order.text];
// Encode the parameters to default for NSMutableURLRequest.
NSData *paramData = [paramDataString dataUsingEncoding:NSUTF8StringEncoding];
// Set the NSMutableURLRequest body data.
[nsMutableURLRequest setHTTPBody: paramData];
// Create NSURLConnection and start the request.
NSURLConnection *nsUrlConnection=[[NSURLConnection alloc]initWithRequest:nsMutableURLRequest delegate:self];
I'd appreciate any ideas or guidance. Thanks.
I believe you have two problems:
You didn't escape quotas (put \ before all of them)
You don't need to put text "name", "location" and etc in parameters (it's not a problem per se, just a style thing)
Also, I would recommend to work with NSDictionary and convert it to JSON when you need to (it will save you a lot of nerves for unescaped quotas, missing bracket and so on).
Look this question how to convert NSDictionary to JSON:
Generate JSON string from NSDictionary in iOS

How to use json data from localhost in objective-c?

- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view.
NSURL *site_url = [NSURL URLWithString:[NSString stringWithFormat:#"%#/json/data/post?sid=%#", SECURE, PASSCODE]];
NSData *jsonData = [NSData dataWithContentsOfURL:site_url];
NSError *error = nil;
NSDictionary *dataDictionary = [NSJSONSerialization JSONObjectWithData:jsonData options:0 error:&error];
self.items = dataDictionary;
}
I am trying to parse json data. It works fine with data from the live server. However, when I change the link to http://localhost:8090. It stops working.
Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: 'data parameter is nil'
I can access it from the data from the web browser. Does anyone know why is that?
Does it work on emulator and not on a real device?
You should never use localhost when developing apps, use the local IP for the server instead. Localhost is the machine who make the call to the server. When you try on the emulator and you have the server on the same machine it works because they are the same.
But when you try on a real device, localhost is the device, and the device doesn't have a server installed, so it will fail.
BTW, to test on a real device, it has to be connected to the same network.
What you need here is to implement the NSURLConnection and receive data from it
Check out this
NSURL *site_url = [NSURL URLWithString:[NSString stringWithFormat:#"%#/json/data/post?sid=%#", SECURE, PASSCODE]];
NSURLRequest *req = [NSURLRequest requestWithURL:site_url];
NSURLConnection *con = [[NSURLConnection alloc] initWithRequest:req delegate:self];
[con start];
and from the delegates get the response
this document can help you a lot in this

StoreKit verification error 21002: The data in the receipt-data property was malformed

On a iPhone 4/iOS 4 device, sandbox App Store is reporting this error during verification:
21002: The data in the receipt-data property was malformed.
On a iPhone 5/iOS 6 device, the same code works (status == 0, receipt returned) without any problems.
I've restarted the device, made sure the Apple ID is logged out, even made a new test user account. Same result. Any ideas?
This Error means the JSON Object that you have created to send for verification is not in correct format.
{
"receipt-data" : "(receipt bytes here)"
}
So My suggestion is to Debug the same on iPhone 4/iOS 4. In case, you are Using Json Framework to create JSON object (for receipt validation) it will work only with iOS 5.0 & above.
Adding Code I had Implemented a few months I Used SBJson to write N parse.
NSString *base64TxReceiptStr=[NSData Base64Encode:transaction.transactionReceipt];
SBJsonWriter *writer = [[SBJsonWriter alloc] init];
NSDictionary *command = [NSDictionary dictionaryWithObjectsAndKeys:
base64TxReceiptStr, #"receipt-data",
nil];
NSString *jsonString = [writer stringWithObject:command];
NSData *requestBody=[jsonString dataUsingEncoding:NSUTF8StringEncoding];
NSMutableURLRequest *txReceiptVerificationRequest=[[NSMutableURLRequest alloc] initWithURL:[NSURL URLWithString:#"https://sandbox.itunes.apple.com/verifyReceipt"]];
[txReceiptVerificationRequest setHTTPBody:requestBody];
[txReceiptVerificationRequest setHTTPMethod:#"POST"];
NSURLResponse *response=nil;
NSError *error=nil;
NSData *responseData=[NSURLConnection sendSynchronousRequest:txReceiptVerificationRequest returningResponse:&response error:&error];
NSString * receivedString=[[NSString alloc] initWithData:responseData encoding:NSUTF8StringEncoding];
SBJsonParser *parser = [[SBJsonParser alloc] init];
NSDictionary *aobject =[parser objectWithString:receivedString];`
For your sandbox environment use: https://sandbox.itunes.apple.com/verifyReceipt
For actual verification use: https://buy.itunes.apple.com/verifyReceipt
You can check this at Apple's official page.

Using NSURLCredentialPersistenceForSession while request and then clearing the credentials on logout still persist the cerdentials

I am using NSURLCredentialPersistenceForSession within didReceiveAuthenticationChallenge of NSURLConnection delegate method while login.
Now when I logout and use this code for clearing the storage..
NSURLCredentialStorage *credentialStorage = [NSURLCredentialStorage sharedCredentialStorage];
NSDictionary *credentialsDicationary = [credentialStorage allCredentials];
NSLog(#"credentialsDicationary..%#",[credentialsDicationary description]);
for (NSURLProtectionSpace *space in [credentialsDicationary allKeys]) {
NSDictionary *spaceDictionary = [credentialsDicationary objectForKey:space];
NSLog(#"spaceDictionary..%#",[spaceDictionary description]);
for (id userName in [spaceDictionary allKeys]) {
NSURLCredential *credential = [spaceDictionary objectForKey:userName];
[credentialStorage removeCredential:credential forProtectionSpace:space];
}
}
But when I suddenly login again exactly after logout the login happens with wrong credentials. Please let mw know how to clear the cache. It works if I relogin after some 5 secs of time.
Thanks in advance..
AJ
If you're using NSURLSession, invalidate the session and create a new one, e.g.:
[self.session invalidateAndCancel];
self.session = [NSURLSession sessionWithConfiguration:[NSURLSessionConfiguration defaultSessionConfiguration] delegate:self delegateQueue:nil];
This will clear session-scoped credentials.
If you use NSURLCredentialPersistenceForSession to create the credential then the app stores the credential for the entire session until the app is closed.
You can work around this by either:
changing the url (like appending '#' to the end of the url)
Use NSURLCredentialPersistenceNone and provide the credentials with each nsurlrequest
Append auth info to the url (http://username:password#mywebsite.com), instead of using creds
Append auth info to the request header, instead of using creds
//Pseudo code for appending to header:
NSString *authString = [NSString stringWithFormat:#"%#:%#", self.loginCreds.username, self.loginCreds.password];
NSData *stringData = [authString dataUsingEncoding:NSUTF8StringEncoding];
authString = [NSString stringWithFormat:#"Basic %#", [stringData base64EncodedString]];
[[self requestHeader] setValue:authString forHTTPHeaderField:#"Authorization"];
It's possible to remove the credential but it can take minutes before it is actually removed. However, I don't remember how its done.. It's either done the way you mentioned in the question or through the keychain.
I had the same issue and I tried clear the credential storage, cookies associated with url and even trying to reset the session but nothing seemed to work, finally I just resorted to adding a a random query string value to the end of the url and that did the trick for me
// Random number calculated.
NSInteger randomNumber = arc4random() % 16;
NSURL* apiURL = [NSURL URLWithString:#"https://localhost/api/"];
[[RKObjectManager sharedManager] getObjectsAtPath:[NSString stringWithFormat:#"%#getUser?randomNumber=%d",apiURL,randomNumber]
parameters:nil
success:successBlock
failure:failureBlock];
So instead of trying to remove current cached credentials (which seemed impossible) just use a "fresh" url so there aren't any cached objects associated with it.
I was facing the same problem, now it works.
Using NSURLConnection this issue can be fixed easily by adding a random number to the end of the URL:
So, search for your URLRequest and append the random number to URLRequest
NSInteger randomNumber = arc4random() % 999;
NSString *requestURL = [NSString stringWithFormat:#"%#?cache=%ld",yourURL,(long)randomNumber];
NSURL *URLRequest = [NSURL URLWithString:requestURL];
And make sure you have a random number at the end of all URLs you are calling.

Resources