Почему пользователю без прав администратора разрешен доступ к моей индексной странице в приложении Rails? (Разработать самоцвет)

Я использую Devise Gem для аутентификации пользователей. Пользователи создают ответы в форме в приложении, и только администратор должен иметь возможность просматривать результаты, а также индекс всех пользователей, заполнивших форму. У меня есть 2 пользователя, у одного для атрибута admin установлено значение «true», а для другого - «false» (ранее «nil»)

Поведение я ожидаю

Только пользователи, для атрибута admin которых установлено значение «true», должны иметь доступ к представлениям шоу и индекса.

Что на самом деле происходит

Когда я использовал только метод authenticate_user!, который включен в Devise, он работал правильно, так как пользователи могли видеть страницы шоу и индекса, только если они вошли в систему. Однако когда я добавил метод аутентификации, чтобы разрешить просмотр шоу только пользователям с правами администратора и индексировать страницы внезапно, каждый пользователь мог видеть их независимо от того, вошел он в систему или нет. Я не понимаю, почему происходит такое поведение, поскольку теперь только авторизованные пользователи с правами администратора должны иметь возможность видеть эти страницы в соответствии с логикой кода, насколько я понимаю. current_user также является методом Devise Gem.

У меня есть следующий код в моем контроллере Formularios (forms):

class FormulariosController < ApplicationController
  before_action :set_formulario, only: [:show, :edit, :update, :destroy]
  before_action :authenticate, only: [:show, :index]

  # GET /formularios
  # GET /formularios.json
  def index
    @formularios = Formulario.all
  end
.
.
.
.
.

 

  private

    def authenticate
      authenticate_user! && current_user.admin?
    end

    # Use callbacks to share common setup or constraints between actions.
    def set_formulario
      @formulario = Formulario.find(params[:id])
    end

    # Never trust parameters from the scary internet, only allow the white list through.
    def formulario_params
      params.require(:formulario).permit(:nombre, :fecha, :FdN, :direccion, :sexo, :email, :telefono, :movil, :profesion, :altura, :peso, :motivos, :especialistas, :dieta, :intolerancia, :detalles_1, :limites, :otro_1, :problema1, :p1, :p2, :p3, :problema2, :p4, :p5, :p6, :problema3, :p7, :p8, :p9, :problema4, :p10, :p11, :p12, :otro_2, :medicacion1, :m1, :m2, :m3, :m4, :m5, :m6, :medicacion2, :m7, :m8, :m9, :m10, :m11, :m12, :medicacion3, :m13, :m14, :m15, :m16, :m17, :m18, :otro_3, :suplemento1, :s1, :s2, :s3, :s4, :suplemento2, :s5, :s6, :s7, :s8, :suplemento3, :s9, :s10, :s11, :s12, :otro_4, :madre, :padre, :abuela_mat, :abuela_pat, :abuelo_mat, :abuelo_pat, :hermanos, :hermanas, :tios, :tias, :ninos, :sobrinos, :activa, :ejercicio1, :e1, :e2, :ejercicio2, :e3, :e4, :ejercicio3, :e5, :e6, :otro_5, :fumas1, :fumas2, :fumado, :alcol1, :alcol2, :alergia1, :alergia2, :habitos1, :habitos2, :habitos3, :habitos4, :galletas_tartas_bolleria, :leche, :huevos, :chocolates_dulces, :carne_roja, :carne_blanca, :pescado_blanco, :pezcado_azul, :carne_procesada, :pan, :te, :cafe, :refresco_lata, :agua, :verdura, :ensalada, :tick, :pecho, :dieta_sana, :motivacion, :desayuno1, :desayuno2, :desayuno3, :almuerzo, :almuerzo2, :almuerzo3, :cena1, :cena2, :cena3, :snacks1, :snacks2, :snacks3, :bebidas1, :bebidas2, :bebidas3)
    end
end

из schema.rb

  create_table "users", force: :cascade do |t|
    t.string "email", default: "", null: false
    t.string "encrypted_password", default: "", null: false
    t.string "reset_password_token"
    t.datetime "reset_password_sent_at"
    t.datetime "remember_created_at"
    t.integer "sign_in_count", default: 0, null: false
    t.datetime "current_sign_in_at"
    t.datetime "last_sign_in_at"
    t.string "current_sign_in_ip"
    t.string "last_sign_in_ip"
    t.datetime "created_at", null: false
    t.datetime "updated_at", null: false
    t.boolean "admin"
    t.index ["email"], name: "index_users_on_email", unique: true
    t.index ["reset_password_token"], name: "index_users_on_reset_password_token", unique: true
  end

РЕДАКТИРОВАТЬ 1: User.rb

class User < ApplicationRecord
  # Include default devise modules. Others available are:
  # :confirmable, :lockable, :timeoutable and :omniauthable
  devise :database_authenticatable, :registerable,
         :recoverable, :rememberable, :trackable, :validatable
end

Можете ли вы опубликовать класс пользователя, хотите проверить метод администратора

srinij 04.06.2018 14:39

@srini вы имеете в виду модель User?

Owen 04.06.2018 14:48
Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
0
2
49
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Что ж, похоже, ваш метод аутентификации ничего не делает, кроме как требует аутентификации пользователя.

Вы можете предпочесть что-то вроде этого:

class FormulariosController < ApplicationController
  before_action :set_formulario, only: [:show, :edit, :update, :destroy]
  before_action :authenticate_user!, only: [:show, :index]
  before_action :authenticate_admin, only: [:show, :index]

  # GET /formularios
  # GET /formularios.json
  def index
    @formularios = Formulario.all
  end
.
.
.
.
.



  private

    def authenticate_admin
      unless current_user.admin?
        redirect_to root_path
      end
    end

    # Use callbacks to share common setup or constraints between actions.
    def set_formulario
      @formulario = Formulario.find(params[:id])
    end

    # Never trust parameters from the scary internet, only allow the white list through.
    def formulario_params
      params.require(:formulario).permit(:nombre, :fecha, :FdN, :direccion, :sexo, :email, :telefono, :movil, :profesion, :altura, :peso, :motivos, :especialistas, :dieta, :intolerancia, :detalles_1, :limites, :otro_1, :problema1, :p1, :p2, :p3, :problema2, :p4, :p5, :p6, :problema3, :p7, :p8, :p9, :problema4, :p10, :p11, :p12, :otro_2, :medicacion1, :m1, :m2, :m3, :m4, :m5, :m6, :medicacion2, :m7, :m8, :m9, :m10, :m11, :m12, :medicacion3, :m13, :m14, :m15, :m16, :m17, :m18, :otro_3, :suplemento1, :s1, :s2, :s3, :s4, :suplemento2, :s5, :s6, :s7, :s8, :suplemento3, :s9, :s10, :s11, :s12, :otro_4, :madre, :padre, :abuela_mat, :abuela_pat, :abuelo_mat, :abuelo_pat, :hermanos, :hermanas, :tios, :tias, :ninos, :sobrinos, :activa, :ejercicio1, :e1, :e2, :ejercicio2, :e3, :e4, :ejercicio3, :e5, :e6, :otro_5, :fumas1, :fumas2, :fumado, :alcol1, :alcol2, :alergia1, :alergia2, :habitos1, :habitos2, :habitos3, :habitos4, :galletas_tartas_bolleria, :leche, :huevos, :chocolates_dulces, :carne_roja, :carne_blanca, :pescado_blanco, :pezcado_azul, :carne_procesada, :pan, :te, :cafe, :refresco_lata, :agua, :verdura, :ensalada, :tick, :pecho, :dieta_sana, :motivacion, :desayuno1, :desayuno2, :desayuno3, :almuerzo, :almuerzo2, :almuerzo3, :cena1, :cena2, :cena3, :snacks1, :snacks2, :snacks3, :bebidas1, :bebidas2, :bebidas3)
    end
end

Затем, если пользователь не является администратором, он перенаправляется на корневой путь приложения для отображения и индексирования.

РЕДАКТИРОВАТЬ

На самом деле я не слишком уверен в том, что authenticate_user! && current_user.admin? делает, поскольку это не часть заявления if else. Конечно, для этого потребуется аутентификация пользователя, но я даже не уверен, что запускает вторая часть ... если не ошибка.

(кстати, я все еще новичок в Rails, поэтому я не знаком со всеми видами синтаксиса Rails)

Это решает проблему. однако я до сих пор не понимаю, почему мой исходный код не удался, поскольку, если текущий пользователь не был администратором, метод аутентификации вернул бы false и, следовательно, не отобразил бы страницу. не могли бы вы объяснить, почему исходный код не удался?

Owen 04.06.2018 15:07

Ну, это мое объяснение части редактирования. Вы используете authenticate_user! && current_user.admin? без включения его в инструкцию if else или unless else, поэтому приложение не знает, что с ним делать. Это просто что-то вроде true && false или true && true и так ...? Мой метод Authenticate_admin перенаправляет пользователя root, если пользователь не является администратором. Это не подразумевается в вашем исходном заявлении authenticate_user! && current_user.admin?. Вы должны быть более откровенными. Devise - это немного волшебно, потому что за ним стоит много кода. Но если вы устанавливаете свои собственные методы, вам нужно быть более конкретным.

Maxence 04.06.2018 15:13

На самом деле, если authenticate_user! выйдет из строя, он перенаправит вас на страницу входа пользователя Devise и не оставит вас, чтобы увидеть действие контроллера. Затем, если вам нужно создать свой собственный метод для входа в систему администратора, вы должны выбрать страницу перенаправления в случае сбоя.

Maxence 04.06.2018 15:18

Также будьте осторожны, вызывая authenticate_user! перед authenticate_admin, потому что authenticate_admin использует метод Devise current_user, тогда вам нужно быть уверенным, что аутентификация пользователя прошла успешно, иначе это может вызвать некоторые ошибки. Как показано в моем приведенном выше коде, методы вызываются в правильной последовательности.

Maxence 04.06.2018 15:30

Другие вопросы по теме