Мне нужно сделать что-то немного необычное.
У меня есть приложение rails, и я хочу добавить конечную точку, чтобы пользователи могли войти в приложение с помощью ajax с другого веб-сайта.
Моя текущая проблема заключается в том, что session
и cookies
не были сохранены из-за того, как я объявляю эту конечную точку, и я не смог ее исправить.
Базовый контроллер 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 вызвать, значения в session
, cookies
и current_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
Но это привело к тому же поведению.
Есть ли способ, которым я могу этого достичь?