#ruby-on-rails #ruby
#ruby-on-rails #ruby
Вопрос:
Могу ли я в любом случае передать значение параметра другому действию, такому как session? Например, для того, чтобы пользователь мог перейти на следующую страницу и так далее, он должен ввести код доступа. Поэтому, если они попытаются изменить URL, чтобы попытаться пропустить ввод кода доступа, они будут перенаправлены. Итак, чего я пытаюсь достичь, так это сохранить код доступа в сеансе
def welcome_access
@code = params[:access_code] == ENV['ACCESS_CODE']
session[:passed_parameter] = @code
if @code
redirect_to users_welcome_path
else
flash[:alert] = "Incorrect access code"
redirect_to request.referer
end
respond_to do |format|
format.html
format.js
end
end
def welcome_submit
@code = session[:passed_parameter]
@welcome_code = @code
if @welcome_code
if params[:user_type] == "patient"
redirect_to new_patient_path
elsif params[:user_type] == "surrogate"
redirect_to surrogate_patients_path
elsif params[:user_type] == "surrogate"
redirect_to new_patient_path
elsif params[:user_type] == "provider"
redirect_to new_provider_path
elsif params[:user_type] == "facilitator"
redirect_to new_facilitator_path
elsif params[:user_type] == "ancillary"
redirect_to new_ancillary_path
elsif params[:user_type] == "administrator"
redirect_to new_administrator_path
elsif params[:user_type] == "emergency"
redirect_to new_emergency_path
elsif params[:user_type] == "paramedic"
redirect_to new_paramedic_path
end
else
redirect_to request.referer
end
end
вот мой модальный код
<div class="modal-box">
<%= form_tag users_welcome_access_path, method: :post do %>
<div class="close">x</div>
<div class="title">Access Code</div>
<div id="modal-container" class="container sm-height">
<div class="buttons">
<div class="header">
<%= label :access_code, "Enter correct access code to continue registration"%>
<%= text_field_tag :access_code %>
</div>
<div class="header" style="margin-top: 15px">
<%= submit_tag 'Continue', class: "btn-submit" %>
<button class="btn-cancel">Cancel</button>
<div class="push"></div>
</div>
</div>
</div>
<% end %>
</div>
Комментарии:
1. что именно здесь не работает?
2. Эта строка
@code = params[:access_code] == ENV['ACCESS_CODE']
просто присвоитtrue
(строки совпадают) илиfalse
(строки не совпадают) значение@code
. Скорее всего, это не то, что вы хотите.3. @maxpleaner что ж, на моей домашней странице localhost: 3000 пользователю предлагается ввести код доступа, чтобы перейти на страницу регистрации localhost: 3000/users/user. приветствие, которое отлично работает, когда пользователь вводит правильный код доступа, оно перенаправляет на эту страницу. НО если вы просто перейдете по URL-адресу и измените его на localhost:000/users/user. приветствую, это позволит пользователю перейти на эту страницу без ввода кода доступа.
4. Итак, если я правильно понимаю, интерфейс запрашивает welcome_submit напрямую, но @code равен нулю, поэтому он перенаправляется на request referrer . Это верно? Вы можете использовать точку останова, чтобы посмотреть, каков поток кода
Ответ №1:
Вероятно, вы захотите выполнить авторизацию / перенаправление с помощью фильтра before. Эти фильтры позволяют определять методы, которые должны вызываться перед каждым методом контроллера. Инструменты аутентификации обычно используют их довольно сильно, поскольку это позволяет вам проверить, аутентифицирован ли пользователь, прежде чем вы перейдете к сути вашего метода.
Например:
class MyController < ApplicationController
before_action :authenticate!
# authenticate! is automatically called before this method
def welcome_access
# user is already authenticated at this point, or else was redirected to request.referer
respond_to do |format|
# ...
end
end
# authenticate! is automatically called before this method
def welcome_submit
# user is already authenticated at this point, or else was redirected to request.referer
case params[:user_type]
when "patient" then redirect_to new_patient_path
# more redirects here...
when "paramedic" then redirect_to new_paramedic_path
end
end
private
def authenticate!
session[:passed_parameter] = params[:access_code] if params[:access_code].present?
if !correct_code?
flash[:alert] = "Incorrect access code"
redirect_to request.referer
end
end
def correct_code?
session[:passed_parameter] == ENV['ACCESS_CODE']
end
end
Несколько других замечаний / предложений:
-
Рассмотрите возможность использования
case
/when
вместо длиннойif
—elsif
цепочки. Смотрите мой пример. -
ответ_to в welcome_access никогда не попадает, потому что вы всегда будете перенаправлены первым. Либо перенаправить welcome access на другую страницу, либо отобразить html.
-
Вместо
redirect_to request.referer
предпочтитеredirect_back
-
Возможно, вы захотите изучить некоторые драгоценные камни, которые обрабатывают аутентификацию для вас. Devise — мощный универсальный инструмент для этого. На практике люди редко используют собственную аутентификацию (если, скажем, они не делают это просто для того, чтобы научиться), а умение использовать gems в вашем проекте само по себе является хорошим навыком. Конечно, это более безопасно.
Удачи!
Комментарии:
1. Вау, спасибо! На самом деле я использую devise для аутентификации. Что я делаю, так это для регистрации учетной записи пользователя, который должен ввести код доступа для продолжения процесса регистрации. У меня есть несколько шагов для регистрации, и я хочу, чтобы пользователь ввел код доступа в целях безопасности. Итак, теперь все работает идеально! Однако мой модал, предлагающий пользователю ввести код доступа, теперь не появится. но все перенаправления работают, если код доступа не находится в сеансе. Вот мой модальный код выше
2. Какое действие отображает модальное?
3. Если страница, которая отображает модальную, поступает с того же контроллера, то before_filter может вообще препятствовать отображению этой страницы. Что-то вроде уловки 22: сначала вам нужно пройти аутентификацию, прежде чем вы сможете перейти к режиму аутентификации, который позволяет вам проходить аутентификацию… Если это то, что происходит, просто измените действие before на
before_action :authenticate!, except: :whatever_the_action_is_that_renders_the_modal
. Это упоминается в документе before_action, но в нем не приводится пример.