您不想禁用CSRF,我已经读到人们认为出于某种原因它不适用于JSON API,但这是一种误解。要使其保持启用状态,您需要进行一些更改:
在服务器端,将一个after_filter添加到您的会话控制器中:
after_filter :set_csrf_header, only: [:new, :create]
protected
def set_csrf_header
response.headers[‘X-CSRF-Token’] = form_authenticity_token
end
这将生成一个令牌,将其放入您的会话中,并将其复制到所选操作的响应标头中。
客户端(iOS),您需要确保已完成两件事。
您的客户端需要扫描所有服务器响应以查找此标头,并在传递时保留它。
... get ahold of response object
// response may be a NSURLResponse object, so convert:
NSHTTPURLResponse httpResponse = (NSHTTPURLResponse)response;
// grab token if present, make sure you have a config object to store it in
NSString *token = [[httpResponse allHeaderFields] objectForKey:@”X-CSRF-Token”];
if (token)
[yourConfig setCsrfToken:token];最后,您的客户需要将此令牌添加到它发出的所有“非GET”请求中:
... get ahold of your request object
if (yourConfig.csrfToken && ![request.httpMethod isEqualToString:@”GET”])
[request setValue:yourConfig.csrfToken forHTTPHeaderField:@”X-CSRF-Token”];
难题的最后一步是了解登录进行设计时,正在使用两个后续的session / csrf令牌。登录流程如下所示:
GET /users/sign_in -> // new action is called, initial token is set // now send login form on callback: POST /users/sign_in <username, password> -> // create action called, token is reset // when login is successful, session and token are replaced // and you can send authenticated requests



