Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
395 views
in Technique[技术] by (71.8m points)

ruby on rails - HTTP authentication between devise and iphone app

I'm new to ruby on rails but I want to send the data from my SQlite database from my iphone app to the rails web app. Like a "sync" service.

I'm using devise for authentication for the web app. I enabled basic HTTP authentication and I can curl into the website for xml or json data. I can also upload data to the website when I set the post headers to JSON and with username and password.

Here's where I'm stuck.

1) How do I keep the user signed in after the 1st login? Do I use http authentication every time I send data to the website? I've read about token authentication but I'm not sure how to use it.

2) I can post JSON data to something like http://localhost:3000/example with the correct username and password. However, it returns the HTML content if the username and passowrd is incorrect. Do I have to write something that returns json data about login success/fialure?

3) To communicate between my iphone app and my web app. Am I correct in writing a RESTful API on the web app side? Do I need to use active resources?

I'm really stuck on the overall big picture of how all this works. Thanks!

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

There's many ways you can do this. What I did to get Devise to return errors to my iphone app that I could interpret (e.g. 401) was create a custom failure app:

# config/initializers/devise.rb
config.warden do |manager|
  manager.failure_app   = CustomFailure
end

# config/initializers/custom_failure.rb
class CustomFailure < Devise::FailureApp     
  def respond
    unless request.format.to_sym == :html
  http_auth
    else
  super
end
  end
end

Otherwise Devise just returns HTML with a redirect response code regardless of whether the login information was correct or incorrect.

Since my app required users to authenticate against my rails backend, I implemented a simple login system like this:

#app/controllers/pages_controller.rb
before_filter :authenticate_user!, :only => [:login]
ssl_required :login # you have to set up ssl and ssl_requirement


def login
  @user = current_user
  respond_to do |format|
    format.html {render :text => "#{@user.id}"} 
    format.xml {render :text => "#{@user.id}" }   
  end
end

#config/routes.rb
match '/login',       :to => 'pages#login'

Then in the iphone app you can validate by sending a GET request to /login like this (I use ASIHTTPRequest because it's awesome):

- (void) validate_login:(NSString*)name :(NSString*)pwd
{   
    NSURL *login_url = [NSURL URLWithString:@"https://mysite.com/login"];
    ASIHTTPRequest *request = [ASIHTTPRequest requestWithURL:login_url];
    [request setDelegate:self];
    [request setUsername:name];
    [request setPassword:pwd];  
    [request addRequestHeader:@"Accept" value:@"application/xml"]; 
    [request startAsynchronous];    
}

- (void)requestFinished:(ASIHTTPRequest *)request
{
if ([request responseStatusCode] != 200) {
  [self requestFailed:request];
}
    else {
  // authentication successful, store credentials
        NSUSerDefaults* defaults = [NSUserDefaults standardUserDefaults];
    [defaults setValue:[request username] forKey:@"username"];
        [defaults setValue:[request password] forKey:@"password"];
    }
}


- (void)requestFailed:(ASIHTTPRequest *)request
{
    NSLog(@"failed with error: %d %@", [request responseStatusCode], [error localizedDescription]);
    // tell user incorrect username/password    
}

Then whenever you need to post data to the app you can retrieve the username and password from user defaults and attach them to the request. If you need to be more secure, you can store them in the Keychain.

I'm sure there are better ways to do this, but hopefully this can get you thinking about API authentication strategies.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...