2017-02-04 2 views
0

В моем приложении я пытаюсь вручную сделать сеансы разработки непригодными, установив session_validity_token.Rails: ошибка при создании сеанса разработки

Как это сделать:

  • Разрабатывают модель пользователя имеет столбец с именем session_validity_token
  • У меня также есть SeesionHistory модель, которая имеет тот же столбец

В моей инициализации DEViSE ...

Warden::Manager.after_set_user except: :fetch do |user, warden, opts| 
    user.update_attribute(:session_validity_token, Devise.friendly_token) if user.session_validity_token.nil? 
    warden.raw_session["validity_token"] = user.session_validity_token 
end 

Warden::Manager.after_fetch do |user, warden, opts| 
    unless user.session_histories.unblocked.where(session_validity_token: warden.raw_session["validity_token"]).exists? 
    warden.logout 
    end 
end 

... когда пользователь подписывается или поднимается, я устанавливаю validity_token сохраненного Cookie пользователям session_validity_token. Если у Пользователя еще нет (регистрация), я создаю токен.

... при получении URL-адреса я проверяю до авторизации пользователя, если существует разблокированный сеанс для этого токена. Если нет, пользователь выйдет из системы.

В ApplicationController ...

def after_sign_in_path_for(resource_or_scope) 
    session = SessionHistory.create(user_id: current_user.id, session_validity_token: current_user.session_validity_token) 
    current_user.update_attribute(:session_validity_token, Devise.friendly_token) 

    request.env['omniauth.origin'] || stored_location_for(resource) || root_path 
end 

... после того, как пользователь получает вход, я создаю SessionHistory запись и просто установить его session_validity_token к пользователям токенов, а затем воссоздать Пользователь маркера.

К сожалению, я получаю следующее сообщение об ошибке:

NoMethodError in Users::SessionsController#create
undefined method `session_validity_token' for nil:NilClass

Вот является SessionController # Создать действие:

def create 
    if User.where("email = '#{params[:user][:login]}' or username = '#{params[:user][:login]}'").exists? 
     @user = User.find(User.where("email = '#{params[:user][:login]}' or username = '#{params[:user][:login]}'").first.id) 
     if @user.confirmed? || ((Time.now - @user.created_at).to_i/(24 * 60 * 60)) < 1 
      super 
     else 
      redirect_to new_user_confirmation_path(q: "unconfirmed") 
     end 
    else 
     flash[:alert] = "The email or username does not match any accounts" 
     redirect_to new_user_session_path 
    end 
end 

Так что я предполагаю, что я сделал что-то неправильно при обращении лексемы с Warden ...

Пожалуйста, спросите, нужна ли вам дополнительная информация.

+1

Я не являюсь экспертом в использовании 'devise', но я не могу найти столбец с именем' session_validity_token' в любом из моих приложений или в 'devise'-источнике, поэтому мне интересно, является ли то, что у вас есть, это столкновение пространства имен с две настройки для 'session_validity_token'? У вас есть возможность переименования символа в вашей модели 'SessionHistory'? –

+0

Спасибо за этот хороший момент! Я думаю, что это действительно проблема. Я изменил название столбца на что-то абстрактное и, похоже, работает нормально, хотя я все еще его тестирую. Вы можете написать ответ, чтобы закрыть этот вопрос. Еще раз спасибо! Я бы потратил много часов, чтобы найти то, что я сделал неправильно. – jonhue

ответ

1

У вас может возникнуть столкновение пространства имен между двумя настройками с именем session_validity_token. Это не естественно в модели Devise (и нет в источнике для devise - я проверил это).

Если это так, и у вас есть власть над источником, подумайте об изменении имени одного или обоих символов session_validity_token, чтобы уточнить конкретное использование и устранить конфликт.

+0

Хотелось бы, если бы какой-нибудь день придумал изначально историю сеанса и блокировку сессии :) – jonhue

Смежные вопросы