Ajax使用Devise on Grape API登录

时间:2013-04-14 01:43:01

标签: ruby-on-rails ruby ajax api authentication

我有一个rails应用程序,我正在使用Grape和Devise进行身份验证。该应用程序的范围是向JavaScript前端提供API(因此根本没有ERB)。

添加Warden / Devise相关助手后,类api的一部分< Grape :: API看起来像这样

resource :ticket do
    desc "Returns all tickets for a the requesting user; for admins, returns all tickets."
    get :all do
        authenticated_user
            @all_tickets = Ticket.where(user_id: current_user.id)
        end
    end
end

它工作正常,它调用“authenticated_user”,如果返回用户登录,则返回数据。如果不是,它返回401 - 未授权(使用ajax调用请求json响应)。用户当然必须先到http://domain.com/users/sign_in登录。然后它会重定向到可以进行所有这些调用的应用程序页面。

现在,为了应用程序流程,我需要将登录表单设置为基于ajax的。从用户进入应用程序时起。

我已经按照教程Ajax Login with Devise和其他许多人进行了操作。但这个对我来说更有意义。但是我的结果非常奇怪。

考虑以下JavaScript代码:

$('#login').click(function (e) {
$.ajax({
    url: 'http://api.domain.com/users/sign_in?',
    type: 'post',
    data: {remote: true, commit: "Sign in", utf8: "✓", user: {remember_me: 0, password: "12345678", email: "admin@domain.com"}},
    format: "json",
    xhrFields: { withCredentials: true },
        success: function (data) {
            console.log(data);
        }
    });     
});

请注意,我正在使用cors / rack来执行跨域调用。 有两种情况:

1 - 当我拨打此电话时,我获得状态200 OK。但是,cookie集不足以执行需要身份验证的api调用。因此,api调用返回401 - 未授权。

2 - 如果我将“remember_me”设置为true(或0),并单击登录按钮,则第一次返回200OK。它不会在请求中发送cookie(因为我已经注销,因此还没有cookie)。响应是200 OK,响应标头中有rails cookie。

然而,在那次通话之后,我第二次点击登录按钮,它返回“302暂时移动”,然后另一个请求命中domain.com/ - 之后我通过了身份验证。当我执行需要auth的API调用时,将返回数据。这次发送了cookie(从第一次登录尝试获得的cookie),它在响应头中返回了另一个cookie。这个与我发送的不同,我认为这是因为CSRF。每次发送cookie时,都会使用新令牌返回一个新cookie。

在执行API调用时,我必须使用“xhrFields:{withCredentials:true}”才能在请求中发送cookie,因此设计可以对API调用者进行身份验证。因此,如果我使用默认的Devise表单登录,那么数据将毫无困难地返回。

另一种选择是沿着请求发送CSRF令牌(从HTML的元数据中获取),但正如我上面解释的那样,我正在构建一个客户端JS客户端,并且页面不会在rails中呈现本身。

有没有办法使用ajax使用Devise登录,而无需拨打两次电话?

提前致谢! DD

0 个答案:

没有答案