Ok, so I have an application that takes a name and email and saves them in a database via URL GET method. This was the only way I could figure it out from the tutorials I read on google. But I noticed if you just go to the page on my server with the php code, it just inserts a blank row into the database.
How can I avoid this?
Also, can anyone critique my code to make it more secure?
Code:
- (IBAction)saveUsername:(UIButton *)sender {
if ([self checkFields]) {
//Show activity indicator
[UIApplication sharedApplication].networkActivityIndicatorVisible = YES;
[activityIndicator startAnimating];
//Save username
NSUserDefaults *applicationDefaults = [NSUserDefaults standardUserDefaults];
//Save the device ID, may be useful to use as ID for 'accounts'
UIDevice *myDevice = [UIDevice currentDevice];
NSString *deviceUDID = [myDevice uniqueIdentifier];
//Save in database
NSString *post =[NSString stringWithFormat:@"un=%@&em=%@&UDID=%@",username.text, email.text,deviceUDID];
NSString *hostStr = @"http://www.site.net/adduser.php?";
hostStr = [hostStr stringByAppendingString:post];
NSData *dataURL = [NSData dataWithContentsOfURL: [NSURL URLWithString: hostStr]];
NSString *serverOutput = [[NSString alloc] initWithData:dataURL encoding: NSASCIIStringEncoding];
if([serverOutput isEqualToString:@"Yes"]){
//Save in XML
[applicationDefaults setObject:username.text forKey:@"Username"];
[applicationDefaults setObject:email.text forKey:@"UserEmail"];
[applicationDefaults setObject:deviceUDID forKey:@"DeviceUDID"];
//Save
[applicationDefaults synchronize];
//Debugging
NSLog(@"User Added");
//Hide activity indicator
[UIApplication sharedApplication].networkActivityIndicatorVisible = NO;
[activityIndicator stopAnimating];
//Dismiss
[self dismissModalViewControllerAnimated:YES];
}
else {
//Network error or user exists
NSLog(@"User Not Added");
UIAlertView *networkError = [[UIAlertView alloc] initWithTitle:@"Uh Oh!" message:@"Seems you may be having network problems, please connect to a network and try again." delegate:self cancelButtonTitle:@"OK" otherButtonTitles:nil];
[networkError show];
[networkError release];
}
}
}
adduser.php
PHP Code:
<?
$con = mysql_connect("localhost","..","..");
if (!$con) {
die('Could not connect: ' . mysql_error());
}
mysql_select_db("_master", $con);
//Grab username, email, and device ID from URL
$u = $_GET['un'];
$e = $_GET['em'];
$udid = $_GET['UDID'];
//Put it in the database
$query = mysql_query("INSERT INTO users (Username, Email, UDID) VALUES ('$u', '$e', '$udid')");
//Check to see if its there
$search = mysql_query("SELECT UDID FROM users WHERE UDID='$udid'");
So create a web service instead... or maybe just put logic into your PHP code to not create a record when there is no data to insert.
Also, now is probably not the best time to create an app that grabs the device UDID. Considering all the recent discussion on tech sites about that particular API.
__________________ Recall It!Tag your notes. Tag your photos. Tag your thoughts. Tag your life.
I think the base bug is that you're not starting 'post' with a question mark. A GET URL is http://site.com?variable1=data&variable2=data etc. You just appended the data stuff to hte host unless I missed something (which is possible, I just woke up).
As for improvements, might I suggest adding some error checking? Your PHP just blindly runs with the assumption that it could only be called by the iphone app. It should be validating the integrity of the data before posting it to a database. Is there an email address? Is there a UDID? etc, it's just firing blind.
BTW, it's usually normal to use POST for operations that result in data changes. GET is typically reserved for queries, but this isn't probably a huge deal in this case if you're adding data to rows instead of doing other operations. I remember hearing of Google's spider accidentally destroying some websites that had data-changing links that used the GET method, for instance.
So create a web service instead... or maybe just put logic into your PHP code to not create a record when there is no data to insert.
Also, now is probably not the best time to create an app that grabs the device UDID. Considering all the recent discussion on tech sites about that particular API.
I've heard about web services but i've never actually seen a tutorial on one. Guess i'll start searching. Also, how could I check in my php to only allow queries from mobile devices?
Like I said, this was the only way I could figure out how to do this, there will be a lot more database implementation going on so I want to make sure its secure and up to date with the current ways.
So create a web service instead... or maybe just put logic into your PHP code to not create a record when there is no data to insert.
Also, now is probably not the best time to create an app that grabs the device UDID. Considering all the recent discussion on tech sites about that particular API.
BTW, you're not doing any string safing on you $u, $e, and $udid. You insert them directly into your SQL statement and they could contain breakout characters to run arbitrary commands against your database.
Use mysql_real_escape_string() to safe those strings up, and be sure to limit the rights on the user your PHP script is using to connect to the database.
BTW, you're not doing any string safing on you $u, $e, and $udid. You insert them directly into your SQL statement and they could contain breakout characters to run arbitrary commands against your database.
Use mysql_real_escape_string() to safe those strings up, and be sure to limit the rights on the user your PHP script is using to connect to the database.
Yes thank you I just did that.
I just installed ASIHTTPRequest into my application. It seems to be documented very well, would this be a more appropriate solution for what i am trying to accomplish?
I just installed ASIHTTPRequest into my application. It seems to be documented very well, would this be a more appropriate solution for what i am trying to accomplish?
I've used ASIHTTPRequest to POST, it was very straightforward.
Apple is deprecating the UDID for privacy and other reasons.
Exactly.
You can still easily create your own unique ID (via CFUUIDCreate); it just won't be tied to the device (it'll be tied to the pairing of the device and your app, or the user and your app, depending on how you do it and depending on if the user uses multiple devices or simply upgrades to a new device periodically by restoring from a backup of the previous device). But it would create unnecessary headaches for you if you start off by using the UDID, and then have to try to migrate that somehow down the road.
Quote:
Originally Posted by rappa819
Yes thank you I just did that.
I just installed ASIHTTPRequest into my application. It seems to be documented very well, would this be a more appropriate solution for what i am trying to accomplish?
Quote:
Originally Posted by Thunderscreech
I've used ASIHTTPRequest to POST, it was very straightforward.
+1.
ASIHTTPRequest is a very robust library. Definitely the way to go for, I'd say, 98% of iOS apps needing to do any HTTP communication.
__________________ Recall It!Tag your notes. Tag your photos. Tag your thoughts. Tag your life.