【问题标题】:Rails 4 iOS Authentication and AuthorizationRails 4 iOS 身份验证和授权
【发布时间】:2014-04-26 22:20:36
【问题描述】:

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

不过,我正在寻找的是我想更好地了解幕后发生的事情。用户登录后,我会从 rails 端发回 X-CSRF-Token 标头(form_authenticity_token),但据我了解,这仅需要从我的 iOS 应用程序传回服务器以执行写入操作服务器(POST、PUT、DELETE)。如果是这种情况,那么我如何向服务器表明自己的身份以获取 GET 请求?

【问题讨论】:

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


    【解决方案1】:

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

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

    • 对于 POST、PUT 和 DELETE,您必须在请求中提供 X-CSRF-Token 作为标头。但是,除了登录请求之外的所有请求都是如此,登录请求需要禁用 X-CSRF-Token 标头要求才能创建会话,但下面会详细介绍。

    首先,这是针对设备安装在 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 即可创建会话的方法,并且您还需要在用户通过身份验证后传回 X-CSRF-Token 以便将来写入行动会成功。

    我在我的会话控制器中使用了以下内容:

    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
    

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

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2011-03-17
      • 1970-01-01
      • 2010-12-07
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多