2015-11-16 3 views
7

Я только начал работать над приложением Rails 4 (4.2.3), где я использую Devise для аутентификации пользователей. Я хочу, чтобы пользователи могли играть с приложением до подписания upp, создав тестовый проект и войти в систему как гостевой пользователь. Когда пользователь подписывает (или входит), я хочу назначить тестовый проект новому текущему пользователю.Rails 4 - Devise, гостевые пользователи останавливают цепочку фильтров

Я следовал этому руководству от Platformatec: https://github.com/plataformatec/devise/wiki/How-To:-Create-a-guest-user

Создание работы пользователей гостя, но при регистрации или с активной сессии гостевой пользователя я получаю следующую ошибку:

Filter chain halted as :require_no_authentication rendered or redirected 

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

def current_or_guest_user 
    if current_user 
    if session[:guest_user_id] && session[:guest_user_id] != current_user.id 
     logging_in 
     guest_user(with_retry = false).try(:destroy) 
     session[:guest_user_id] = nil 
    end 
    current_user 
    else 
    guest_user 
    end 
end 

Как уже упоминалось, создание гостевых пользователей, похоже, очень хорошо работает. Но эта логика никогда не бывает:

# should delete the guest user and clear the session. 
if current_user 
    if session[:guest_user_id] && session[:guest_user_id] != current_user.id 
    logging_in 
    guest_user(with_retry = false).try(:destroy) 
    session[:guest_user_id] = nil 
    end 
    current_user 

Я уверен, что мой гость сеанс пользователя конфликтует с моим новым пользователем, и вызывает эту ошибку DEViSE (так как гостевой пользователь никогда не будет удален на знак вверх):

Filter chain halted as :require_no_authentication rendered or redirected 

Остальная часть моей гостевой логики выглядит примерно так же, как этот связанный гид: https://github.com/plataformatec/devise/wiki/How-To:-Create-a-guest-user. Я также добавил код из абзаца/примера аутентификации: https://github.com/plataformatec/devise/wiki/How-To:-Create-a-guest-user#authentication-this-may-interfere-with-the-current_user-helper.

Любые идеи о том, что мне не хватает, и как я могу получить свой current_or_guest_user, чтобы удалить гостевого пользователя при регистрации и подписании при использовании Devise?

Update

Это как мои маршруты выглядят в данный момент:

devise_for :users, controllers: { sessions: "users/sessions", registrations: "users/registrations" } 

root :to => 'public#index' 

resources :apps 

get 'users/show', to: "users#show" 
get 'users', to: "users#index" 

post 'guests/receive_guest', to: "guests#receive_guest" 

Update 2

В руководстве имеют следующее заявление:

When (and if) the user registers or logs in, we delete the guest user and clear the session variable.

Это не объясняет, как и как это сделать. Я предполагаю, что я должен снова позвонить current_or_guest_user. Но я не уверен, где, так как я не знаком с Devise.

Update 3

Чтобы сделать это немного более ясно. Это шаги, которые я хочу достичь.

  1. Пользователь создает тестовый проект.
  2. При создании тестового проекта создается гостевой пользователь и сеанс. Гость должен быть удален после завершения сеанса или №3.
  3. Если пользователь гостя зарегистрировался, он должен войти в систему, и тестовый проект должен быть назначен новому реальному пользователю.
  4. Гость должен быть удален.
+0

можете ли вы разместить свой файл 'routes.rb', пожалуйста? –

+0

@huzefabiyawarwala Я сделал это сейчас. – Anders

+2

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

ответ

1

Спасибо за ваши ответы skahlert и SsouLlesS. Пропуск стратегии надзора помог, и определение обратных вызовов кажется чистым. Кроме того, у меня были и другие проблемы.

Один из них заключался в том, что мои пользовательские контроллеры Devise никогда не вызывались. Создал еще один вопрос: Rails 4 - devise_for not using custom controllers. Решение состояло в том, что я использовал неправильный URL-адрес в моей модальной форме регистрации. Моя форма теперь выглядит следующим образом:

= form_for(resource, as: resource_name, url: user_registration_path do |f| 

Тогда я сделал, как skahlert предложил и удалить warden strategy из моего приложения.

Как только мой пользовательский дизайн контроллер получил название Я решил переопределить действие create. Это не полностью протестировано, но выглядит так:

# POST /resource 
def create 
    # Delete guest user and reset session. 
    new_user_from_guest = guest_user 
    guest_user(with_retry = false).try(:destroy) 
    session[:guest_user_id] = nil 

    build_resource(sign_up_params) 

    resource.save 
    yield resource if block_given? 
    if resource.persisted? 
    if resource.active_for_authentication? 
     set_flash_message :notice, :signed_up if is_flashing_format? 
     sign_up(resource_name, resource) 

     # Assign the guest users app to the new current user. 
     new_user_from_guest.apps.each do |app| 
     app.user_id = current_user.id 
     app.save! 
     end 
     respond_with resource, location: after_sign_up_path_for(resource) 
    else 
     set_flash_message :notice, :"signed_up_but_#{resource.inactive_message}" if is_flashing_format? 
     expire_data_after_sign_in! 
     respond_with resource, location: after_inactive_sign_up_path_for(resource) 
    end 
    else 
    # Reset test user if signup fails, I have not tested this part yet. 
    guest_user 
    guest_user.apps << new_user_from_guest.apps 
    guest_user.save! 

    clean_up_passwords resource 
    set_minimum_password_length 
    respond_with resource 
    end 
end 

Все работает сейчас. Могли бы сделать некоторые рефакторинг и, возможно, попробовать подход обратного вызова, предложенный SsouLlesS в его ответе.

1

выше ответ не имеет объяснения, метод loggin_in не вызывается, потому что вы не определили свой обратный вызов

В вашем ApplicationController вам нужно определить, а затем установить функцию обратного вызова следующим образом:

define_callbacks :logging_in_user 
set_callback :logging_in_user, :before, :transfer_guest_user_actions_to_current_user 

def transfer_guest_user_actions_to_current_user 
    # todo 
end 

Вы пытались использовать драгоценный камень devise-guests? он реализует из коробки эту функциональность, а не делает это с нуля ...

Проверьте этот контроллер example, который внедряет гостевой вход. Надеюсь, поможет.

+1

Спасибо. Посмотрите на свое решение. Похоже на чистый способ сделать это. Я создал ответ ниже с тем, как я это сделал сейчас, заработал как минимум. Не стесняйтесь предлагать улучшения. – Anders

1

Я думаю, что проблема вызвана стратегией смотрителя guest_user, упомянутой в руководстве. Поскольку DEViSE проверки на действительной сессии надзирателя до входа в систему, он вызывает редирект и сообщение вспышки появляться:

if authenticated && resource = warden.user(resource_name) 
    flash[:alert] = I18n.t("devise.failure.already_authenticated") 
    redirect_to after_sign_in_path_for(resource) 
end 

Так что, если вы строго не нужно, чтобы проверить подлинность! метод для работы с гостевым пользователем, вы можете просто отключить эту стратегию, и она должна работать.

+0

Спасибо. Это помогло. Я создал полный ответ от всего, что я сделал ниже.Не стесняйтесь добавлять улучшения, если вы знаете лучший подход. Благодаря! – Anders

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