我正在使用 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/