HTTP authentication between devise and iphone app

后端 未结 2 1432
礼貌的吻别
礼貌的吻别 2020-12-12 11:05

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

相关标签:
2条回答
  • 2020-12-12 11:38

    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.

    0 讨论(0)
  • 2020-12-12 11:44

    I would recommend taking a look at the documentation provided here

    https://github.com/plataformatec/devise/blob/v1.1.6/README.rdoc

    You might also want two watch the screencasts on the devise.

    Since there are many different ways to handle auth, you should get a better understanding of what is available since devise supports basicAuth and token based auth

    0 讨论(0)
提交回复
热议问题