ios - Rails 4 iOS 身份验证和授权

标签 ios ruby-on-rails ruby-on-rails-4 devise

我正在使用 Devise 和 CanCanCan 来管理用户身份验证和授权,但出于某种原因,即使我在登录时收到成功消息,我的 current_user 对象始终为 nil Rails 端。我不确定断开连接是什么,但成功登录后我无法检索任何资源。

不过,我正在寻找的是我想更好地了解幕后发生的事情。用户登录后,我从 rails 端发回 X-CSRF-Token header (form_authenticity_token),但据我了解,这只需要从我的 iOS 应用程序传回服务器以执行写入的操作服务器(发布、放置、删除)。如果是这样,那么我如何向服务器标识自己的 GET 请求?

最佳答案

经过更多的研究,这就是我总结我最终所做的事情的方式。

  • 对于 GET 请求,您可以使用 iOS 网络库中内置的 cookie 存储。默认情况下,这在 NSURLRequest(和可变变体)类中打开。这几乎就是 GET 所需的全部内容。当然,您必须成功登录才能获取 cookie,并且登录需要 POST。

  • 对于 POST、PUT 和 DELETE,您必须在请求中提供 X-CSRF-Token 作为 header 。但是,除了需要禁用 X-CSRF-Token header 要求才能创建 session 的登录请求外,所有请求都是如此,但更多内容见下文。

首先,这是针对设备安装在 iOS 上登录的实现(对设备登录路由进行了更改,即 <server_url>/users/login.json 而不是默认的 <server_url>/users/sign_in.json ):

- (void)loginWithUsername:(NSString*)username
                 password:(NSString*)password
          completionBlock:(void(^)(id response, NSError *error))block
{
    NSDictionary *loginDictionary = @{@"user" : @{@"email" : username,
                                                  @"password" : password}
                                      };

    // Convert dictionary to NSData for POST body
    NSError *error = nil;
    NSData *data = [NSJSONSerialization dataWithJSONObject:loginDictionary 
                                                   options:0 
                                                     error:&error];

    NSString *postUrlString = [NSString stringWithFormat:@"%@users/login.json", 
                                                             kApiEndpointURL];

    NSMutableURLRequest *request = [NSMutableURLRequest 
                     requestWithURL:[NSURL URLWithString:postUrlString]
                        cachePolicy:NSURLRequestReloadIgnoringCacheData
                    timeoutInterval:kTimeoutInterval];

    [request setHTTPMethod:@"POST"];
    [request setValue:@"application/json" forHTTPHeaderField:@"Content-type"];
    [request setHTTPBody:data];

    // This is the default--here for clarity
    [request setHTTPShouldHandleCookies:YES];

    NSURLSession *session = [NSURLSession sharedSession];

    [[UIApplication sharedApplication] showNetworkActivityIndicator];

    NSURLSessionDataTask *dataTask = 
                             [session dataTaskWithRequest:request 
                               completionHandler:^(NSData *data, 
                                            NSURLResponse *response, 
                                                  NSError *error) {
        // Save the token so we can perform POSTs, PUTS, and DELETEs
        NSHTTPURLResponse *httpResp = (NSHTTPURLResponse*)response;
        self.xcsrfToken = httpResp.allHeaderFields[@"X-CSRF-Token"];

        [[UIApplication sharedApplication] hideNetworkActivityIndicator];
        NSDictionary *json = [NSJSONSerialization JSONObjectWithData:data options:0 error:nil];
        NSLog(@"%@", json);
        dispatch_async(dispatch_get_main_queue(), ^{
            if (block) {
                block(json, error);
            }
        });
    }];

    [dataTask resume];
}
  • 在 Rails 方面,您需要有一种无需 X-CSRF-Token 即可创建 session 的方法,并且您还需要在用户通过身份验证后传回 X-CSRF-Token,以便将来写入行动就会成功。

我在我的 session Controller 中使用了以下内容:

class SessionsController < Devise::SessionsController
    after_filter :set_csrf_header, only: [:create]
    skip_before_filter :verify_authenticity_token, only: [:create]


    def set_csrf_header
        response.headers['X-CSRF-Token'] = form_authenticity_token
    end
end

我的 session Controller 中包含更多内容,但这显示了相关部分。创建操作的请求成功后,我发回 X-CSRF-Token。但是,我跳过了创建时的真实性验证。这意味着虽然创建 session 本身不需要真实性 token ,但它会在操作完成后将一个返回给请求者,以便请求者可以在以后的所有写入操作中使用该 token 。

如果我遗漏了什么或做错了什么,请告诉我,我会更新这个答案。

关于ios - Rails 4 iOS 身份验证和授权,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23317127/

相关文章:

ios - 自动布局和 Facebook Pop

ruby-on-rails - Gitlab 加载时出现错误 502...这正常吗?

mysql - 生成使用数据库中预先存在的数据的模型

ruby-on-rails - Rails actionmailer,在特定时间发送邮件

ruby - Rails 延迟的工作在暂存时停止

ruby-on-rails - rake 数据库 :setup or rake db:create applying wrong username/wrong database

ios - 自动布局 UICollectionView iOS 8

ios - AVCapturePhotoOutput iOS 相机超暗

ios - 什么是 iOS 5 SDK 中的容器 View ?

ruby-on-rails - 如何直接在 ruby​​ 文件中使用循环为 haml 创建表?