Лучший способ начать сеанс динамически с URL

0

Я пытаюсь создать сеанс в Rails только тогда, когда пользователь нажимает кнопку в своем браузере. Какой лучший способ сделать это с помощью jQuery?

Практическое использование для чего-то вроде этого может быть:

  • Предотвращение повторного отображения предупреждения после его закрытия.
  • Вспоминая информацию о пользователях на разных этапах.
  • Сохранение основных одноразовых настроек после завершения действия.

Я придумал это:

HTML:

<button id="startSession">Start a Session!</button>  

JQuery:

$("#startSession").click(function() {
  $.ajax({
    url: "/sessions-manager?add=funkysession"
  });
});

Тогда контроллер будет выглядеть примерно так:

get "/sessions-manager" do
  name = params[:add].to_sym
  session[name] = true  #=> session[:funkysession] = true

  # A session named "funkysession" has now been started
end

Однако я чувствую, что этот способ открыт для использования. Например, люди могут вручную запускать /sessions-manager?add=user session /sessions-manager?add=user и подделывать сеанс пользователя, чтобы получить доступ к защищенным областям моего приложения. Есть ли более безопасный способ начать сеансы?

Теги:
security
session
sinatra

1 ответ

0
Лучший ответ

Я нашел два возможных решения этой проблемы.

Вариант 1: отправка пользовательских заголовков в запрос AJAX

Идея этого заключается в том, чтобы настроить собственный HTTP-заголовок, который будет отправлен с фактическим запросом AJAX, который затем будет проверяться в контроллере. Это означает, что люди не могут успешно взаимодействовать с маршрутом /sessions-manager вручную в своей строке URL веб-браузера. Пользовательские заголовки можно легко установить с помощью jQuery:

$("#startSession").click(function() {
  $.ajax({
    url: "/sessions-manager?add=showpassword",
    beforeSend: function(xhr){xhr.setRequestHeader('foo', 'bar');}
  });
});

И теперь просто проверьте, что ваш пользовательский заголовок присутствует в контроллере:

get "/sessions-manager" do
  if env["foo"] == "bar"
    // Add session
  else
    halt 401 // Authentication required error
  end
end

Замечание об этом подходе: хотя это, безусловно, эффективный метод защиты маршрута /sessions-manager, он все равно может быть скомпрометирован. Люди, которые знают, что делают, могут подделывать заголовки HTTP с помощью инструментов разработчика, поэтому вариант 2 может быть для вас. Тем не менее, это по-прежнему хорошая стратегия для реализации в качестве дополнительного уровня защиты, просто знайте ее пределы.

Вариант 2 (предпочтительный): несколько уровней сеанса

Более эффективное решение, которое было доведено до моего сведения вдохновителем Биткойна Сэмом Фоли, заключается в ограничении объема сеанса, который может быть создан с помощью URL /sessions-manager адреса /sessions-manager session /sessions-manager. Это может быть достигнуто довольно просто, добавив еще один уровень в сеанс, который вы хотите создать, то есть - предоставить родительскому дочернему соединению session. Проверьте это:

get "/sessions-manager" do
  session[:userprefs] ||= {} // Set parent session as empty hash
  name = params[:add].to_sym
  session[:userprefs][:name] = true
end

Намного лучше. Теперь мы можем получить доступ к этой сессии в любом месте нашего приложения (представления или контроллер):

if session[:userprefs][:showpassword] 
  "Password is blah"
end 

Более того, люди не могут подделывать существующие сеансы. Например, кто-то пытается подделать сеанс пользователя, теперь создаст сеанс с именем [:userprefs][:user] который фактически бесполезен.

  • 0
    Так что ... это на самом деле ничего не делает. Вы просто используете существующий механизм сессии Rails очень типичным способом. Это не совсем достойные новости.
  • 0
    Ну нет ... Вопрос заключался в том, чтобы задать лучший способ начать сеанс с помощью URL-адреса, чтобы он не был уязвим для приложения (например, кто-то запускает фальшивый сеанс использования). Извините, что мое решение использует "существующий механизм сессии rails". Может, мне в следующий раз переписать свой ответ, используя PHP-функцию $_SESSION[""] ?
Показать ещё 2 комментария

Ещё вопросы

Сообщество Overcoder
Наверх
Меню