【问题标题】:Rails 6.1.3.2 Unpermitted parameter and User must existRails 6.1.3.2 不允许的参数和用户必须存在
【发布时间】:2021-06-13 13:01:40
【问题描述】:

几年前我在 Rails 4 中开发应用程序,现在很多事情都发生了变化。

本例中我使用 Shire GEM 上传照片:

好的,我的模型:

照片模型:

class Photo < ApplicationRecord

    include ImageUploader::Attachment(:image)

    belongs_to :user

end

用户模型(我只放了几行):

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

  has_one :profile, :dependent => :destroy
  has_many :photos, :dependent => :destroy

end

照片控制器:

class PhotosController < ApplicationController

    before_action :set_photo, only: %i[ show edit update destroy ]
    before_action :authenticate_user!

 def create
    @photo = Photo.new(photo_params)

    respond_to do |format|
       if @photo.save
       format.html { redirect_to @photo, notice: "Photo was successfully created." }
       format.json { render :show, status: :created, location: @photo }
    else
       format.html { render :new, status: :unprocessable_entity }
       format.json { render json: @photo.errors, status: :unprocessable_entity }
    end
 end

private
    # Use callbacks to share common setup or constraints between actions.
    def set_photo
       @photo = Photo.find(params[:id])
    end

    # Only allow a list of trusted parameters through.
    def photo_params
      params.require(:photo).permit(:title, :image_data, :image, :user_id)
    end


 end

    

用户控制器:

class UsersController < ApplicationController


  private

  # Only allow a list of trusted parameters through.

     def set_user
       @user = User.find(params[:id])
     end

     def user_params
       params.require(:user).permit(:id)
     end

 end

最后一件事,在视图中添加照片的表单:

 <%= form_with(model: photo) do |form| %>
   <% if photo.errors.any? %>
     <div id="error_explanation">
      <h2><%= pluralize(photo.errors.count, "error") %> prohibited this photo from being saved:</h2>

      <ul>
         <% photo.errors.each do |error| %>
           <li><%= error.full_message %></li>
         <% end %>
      </ul>
     </div>
   <% end %>

   <div class="field">
     <%= form.label :title %>
     <%= form.text_field :title %>
   </div>

   <div class="field">
     <%= form.label :image %>
     <%= form.file_field :image %>
   </div>
   <%= current_user.id %> // SHOWS USER ID

   //// THIS GENERATE ERROR ////
   <%#= form.hidden_field :user_id => current_user.id %>

   <div class="actions">
     <%= form.submit %>
   </div>
 <% end %>

我有问题的地方。当我以这种方式访问​​它时,我会在日志中看到未经允许的参数:user_id。

但是当我提交表单时,我看到错误“用户必须存在”。

我在 PhotosController 中找到了解决方案并更改了这一行:

def create
   @photo = Photo.new(photo_params)

到:

def create
   @photo = current_user.photos.new(photo_params)

它开始工作了。照片在表格中有 user_id。但我想知道为什么我不能在视图中为照片添加 user_id,例如:

 <%= form.hidden_field :user_id => current_user.id %>

【问题讨论】:

    标签: ruby-on-rails ruby-on-rails-6


    【解决方案1】:

    切勿通过参数将用户 ID 作为明文传递。而是从会话中获取它。对于任何恶意用户来说,使用网络检查器并简单地填写隐藏的输入,然后以任何用户的身份上传一张不合时宜的图片,这都是微不足道的。

    会话 cookie 是加密的,更难篡改。

    class PhotosController < ApplicationController
      before_action :authenticate_user!
      
      def create
        # build the record off the current_user
        @photo = current_user.photos.new(photo_params)
        respond_to do |format|
          if @photo.save
            format.html { redirect_to @photo, notice: "Photo was successfully created." }
            format.json { render :show, status: :created, location: @photo }
          else
            format.html { render :new, status: :unprocessable_entity }
            format.json { render json: @photo.errors, status: :unprocessable_entity }
          end
        end
      end 
      
      private
      # Only allow a list of trusted parameters through.
      def photo_params
        params.require(:photo).permit(:title, :image_data, :image)
      end
    end
    

    但我想知道为什么我不能在视图中为照片添加 user_id,例如:

    current_user.id %>

    因为您使用错误的参数调用该方法。 signature is hidden_field(object_name, method, options = {}) 但如前所述,这是个坏主意。

    【讨论】:

    • 好的,谢谢,这是安全问题,但为什么我收到此错误消息?
    • 我想我的编辑回答了这个问题。应该是form.hidden_field :user_id, value: current_user.id - 但还是不要这样做。
    • 不,不是这个,现在我有了:没有将 Integer 隐式转换为 Hash ;) ps。我不会这样做,只是想知道问题出在哪里。
    • 1 错误禁止保存此照片:用户必须存在 - 添加后,值:
    • 老兄。有更好的事情可以消磨时间。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-09-14
    • 2013-08-01
    • 2023-03-23
    • 1970-01-01
    • 2013-07-25
    相关资源
    最近更新 更多