Showing posts with label ios. Show all posts
Showing posts with label ios. Show all posts

Wednesday, 25 September 2013

HTTP Basic authentication with Rails for iOS

Recently I've been getting into iOS and developing a interesting iOS app (more info coming soon!)

But, as the app is all about showing data of course I needed to create an API in my rails app to feed that data. But, I didn't want someone else to be able to grab it.

The Rails App Side

Configure a custom MIME type

First thing I did was set up a custom mime type in initializers/mime_types.rb:
Mime::Type.register_alias "text/json", :theapp
That let me call urls like /give_me_data.theapp

Add the 'respond_to'

In the applicable controllers add a respond_to (well, I already had one, so add to it):
respond_to :html, :xml, :theapp

Make templates with json_builder

I luuuvvvvv the json_builder gem. So I created a whack of templates with the .json_builder extension. Because of the mime type setting it would automatically get called.

Add the http_authentication stuff

I am a little bit lazy, so, I just chuck this into my application_controller. That means that all :theapp requests need authentication:

protected
def http_basic_authentication
    if request.format == :ios
        authenticate_or_request_with_http_basic do |username, password|
            username == 'myAmazingApp' && password == 'theBestestPasswordEver'
        end
    end
end

The iOS app side

The URLs

Simply chuck your authentication stuff into your urls:
NSString *const RegionDataBaseURL = @"http://myAmazingApp:theBestestPasswordEver@localhost:3000/regions/%@.theapp";

Pulling...Data

I do my stuff like this (thanks to Ray Wenderlich):
  dispatch_async(kBgQueue, ^{
    NSURL *url = [NSURL URLWithString: [NSString stringWithFormat:RegionDataBaseURL, [self.region permalink]]];
    
    NSData* data = [NSData dataWithContentsOfURL: url];
    [self performSelectorOnMainThread:@selector(fetchedRegionData:)
                           withObject:data waitUntilDone:YES];
  });
Yes, I could also put the username and password in some other place and sub it into the URL, but brute force works for now.

Like I say, I am starting out in iOS so maybe this is too noddy for all you pros, but, it works.