关于Rails API的持久会话

时间:2019-05-03 01:27:01

标签: ruby-on-rails ruby session csrf

我需要做一些不寻常的事情。

我有一个Rails应用程序,我想添加一个端点,以便用户可以使用其他网站上的Ajax登录该应用程序。

我当前的问题是,sessioncookies并没有以我声明该端点的方式保留下来,而且我还无法修复它。

基本API控制器

class ApiController < ActionController::Base

  before_filter :authorize

  private

  def authorize
    return render json: {}, status: 401 if request.headers['x-auth-token'] != ENV.fetch('CFX_AUTH_TOKEN')
  end
end

具有端点的控制器

class CfxController < ApiController
  def login
    body = {}
    body["user[email]"] = params[:email].downcase
    body["user[password]"] = params[:password]

    begin
      user = User.authorize(body)

      session[:user_id] = user.id
      session[:auth_token] = user.token
      cookies.permanent.signed[:user_id] = user.id
      cookies.permanent.signed[:auth_token] = user.token
      @current_user = user

      render json: { user: { id: user.cfx_id, auth_token: user.token } }, status: 200
    rescue Flexirest::HTTPServerException => ex
      render json: {}, status: ex.status
    rescue Flexirest::HTTPClientException => ex
      render json: ex.result.errors.to_json, status: ex.status
    end
  end
end

路线声明

 post   '/api/login' => 'cfx#login'

这是调用端点的ajax调用:

$.ajax({
  url: 'https://mywebsite.com/api/login',
  type: "POST",
  data: $form.serialize(),
  headers: {
    'x-auth-token': 'XXXX',
  },
  dataType: "json",
  success: function(resp) {
    reloadPage();
    success('emailLoginSuccess');
  },
  error: function(resp) {
    if (resp.status === "403") {
        reloadPage();
    } else {
      $scope.$apply(function() {
          vm.submitting = false;
          vm.loginError = true;
      });
    }
  }
});

我希望,如果我使用使ajax调用sessioncookiescurrent_user_id的值的浏览器打开该网站,那么该用户将被记录。但是事实并非如此。

我认为这与protect_from_forgery的默认值是null_session有关。因此,我尝试在基础ApiController上进行设置:

protect_from_forgery with: :exception
# since the request is made from a different website I don't have the CSRF token
skip_before_action :verify_authenticity_token

但这导致了相同的行为。

有什么办法可以做到这一点?

0 个答案:

没有答案