【问题标题】:HTTP authentication between devise and iphone app设计和 iPhone 应用程序之间的 HTTP 身份验证
【发布时间】:2011-09-22 09:42:01
【问题描述】:

我是 ruby​​ on rails 的新手,但我想将我的 SQlite 数据库中的数据从我的 iphone 应用程序发送到 rails 网络应用程序。类似于“同步”服务。

我正在使用 devise 对 Web 应用程序进行身份验证。我启用了基本的 HTTP 身份验证,我可以进入网站获取 xml 或 json 数据。当我将帖子标题设置为 JSON 并使用用户名和密码时,我还可以将数据上传到网站。

这就是我卡住的地方。

1) 如何让用户在第一次登录后保持登录状态?每次向网站发送数据时是否都使用 http 身份验证?我已经阅读过令牌身份验证,但我不知道如何使用它。

2) 我可以使用正确的用户名和密码将 JSON 数据发布到 http://localhost:3000/example 之类的地方。但是,如果用户名和密码不正确,它会返回 HTML 内容。我是否必须编写一些返回有关登录成功/失败的 json 数据的内容?

3) 在我的 iphone 应用程序和我的网络应用程序之间进行通信。我在 Web 应用程序端编写 RESTful API 是否正确?我需要使用活动资源吗?

我真的很想知道这一切是如何运作的。谢谢!

【问题讨论】:

    标签: ruby-on-rails api devise titanium http-authentication


    【解决方案1】:

    我建议您查看此处提供的文档

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

    您可能还希望在设备上观看两个屏幕录像。

    由于有许多不同的方式来处理身份验证,因此您应该更好地了解可用的方法,因为设计支持 basicAuth 和基于令牌的身份验证

    【讨论】:

    • 谢谢亚伦。我已多次阅读自述文件。我还看过 railscast 上的截屏视频。我只需要某种我可以遵循的框架。有太多的概念,我很难把它们放在一起。
    【解决方案2】:

    有很多方法可以做到这一点。为了让 Devise 将错误返回到我可以解释的 iPhone 应用程序(例如 401),我所做的是创建一个自定义失败应用程序:

    # 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
    

    否则,无论登录信息是否正确,Devise 都只会返回带有重定向响应代码的 HTML。

    由于我的应用要求用户对我的 Rails 后端进行身份验证,因此我实现了一个简单的登录系统,如下所示:

    #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'
    

    然后在 iphone 应用程序中,您可以像这样向 /login 发送 GET 请求来验证(我使用 ASIHTTPRequest,因为它很棒):

    - (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    
    }
    

    然后,当您需要将数据发布到应用程序时,您可以从用户默认值中检索用户名和密码并将它们附加到请求中。如果您需要更安全,可以将它们存储在 Keychain 中。

    我确信有更好的方法可以做到这一点,但希望这可以让您思考 API 身份验证策略。

    【讨论】:

    • 嗨 Johnny,我启用了基本的 http 身份验证,并尝试实现此功能,每次尝试访问 localhost:3000/… 时,都会收到“{”错误“:”您需要登录或注册在继续之前。"}" 你的想法?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2013-03-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-03-09
    • 1970-01-01
    相关资源
    最近更新 更多