A
A
Artyom2019-07-04 18:23:03
API
Artyom, 2019-07-04 18:23:03

Updated!!! Rails 5.2 API mode. How to get rid of ActiveSupport::MessageVerifier::InvalidSignature when trying to pass form-data?

I have a Nuxt/Rails application. It is necessary to send a picture from the front to the backend. I do it like this:

save() {
  const params = new FormData()
  const testimonial = this.testimonial
  delete testimonial.image_name

  for (const field in testimonial) {
    params.append(field, testimonial[field])
  }

  const request = this.id
    ? this.$axios.put(`${this.loadUrl}/${this.id}`, params, {
        headers: {
          'Content-Type': 'multipart/form-data'
        }
      })
    : this.$axios.post(this.loadUrl, params, {
        headers: {
          'Content-Type': 'multipart/form-data'
        }
      })
  
  request
    .then(({ status }) => {
      if (Number(status) === 200) this.success = 'Отзыв успешно обновлён'
      if (Number(status) === 201) this.success = 'Отзыв успешно добавлен'
      setTimeout(() => {
        this.$router.push('/testimonials/')
      }, 1000)
    })
    .catch(error => {
      this.error = error + ''
    })
}

Here are the headers that are generated when the method is processed:
General:
  Request URL: http://localhost:3000/admin/v1/testimonials
  Request Method: POST
  Status Code: 500 Internal Server Error
  Remote Address: [::1]:3000
  Referrer Policy: no-referrer-when-downgrade
Responce Headers:
  Access-Control-Allow-Methods: GET, POST, PUT, PATCH, DELETE, OPTIONS, HEAD
  Access-Control-Allow-Origin: *
  Access-Control-Expose-Headers: 
  Access-Control-Max-Age: 1728000
  Content-Length: 14476
  Content-Type: application/json; charset=UTF-8
  Vary: Origin
  X-Request-Id: f8d6116f-31c7-4644-97c0-e92502fe0f06
  X-Runtime: 0.057866
Request Headers:
  Accept: application/json, text/plain, */*
  Accept-Encoding: gzip, deflate, br
  Accept-Language: ru-RU,ru;q=0.9,en-US;q=0.8,en;q=0.7
  Authorization: Bearer eyJhbGciOiJIUzI1NiJ9.eyJzdWIiOiIxIiwic2NwIjoidXNlciIsImF1ZCI6bnVsbCwiaWF0IjoxNTYyMjQ4MjIyLCJleHAiOjE1NjIyNTE4MjIsImp0aSI6ImM0Y2Y4NjViLTUxOTEtNDk0Ni04YTg3LTQ3MmZjYzczYzA5NCJ9.7wNl04ar8u6TmK8OEirKJecQCjJxF_hgVtfnknQKyWk
  Cache-Control: no-cache
  Connection: keep-alive
  Content-Length: 2186254
  Content-Type: multipart/form-data; boundary=----WebKitFormBoundary3BAEPvtfoHgJ0XC4
  Host: localhost:3000
  Origin: http://localhost:4000
  Pragma: no-cache
  Referer: http://localhost:4000/testimonials/edit/
  User-Agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/73.0.3683.103 Safari/537.36 OPR/60.0.3255.170
Form Data:
  name: Иван
  patronymic: 
  surname: 
  userpic: 
  company: 
  object_photo_1: (binary)
  object_photo_2: null
  object_photo_3: null
  video: 
  text: Отзыв

The server spits the 500th error:
Started POST "/admin/v1/testimonials" for ::1 at 2019-07-04 17:39:58 +0300
Processing by Admin::TestimonialsController#create as JSON
  Parameters: {"name"=>"Иван", "patronymic"=>"", "surname"=>"", "userpic"=>"", "company"=>"", "object_photo_1"=>#<ActionDispatch::Http::UploadedFile:0x00007fa8ec2b6b18 @tempfile=#<Tempfile:/tmp/RackMultipart20190704-8689-cyzaac.jpg>, @original_filename="filename.jpg", @content_type="image/jpeg", @headers="Content-Disposition: form-data; name=\"object_photo_1\"; filename=\"filename.jpg\"\r\nContent-Type: image/jpeg\r\n">, "object_photo_2"=>"null", "object_photo_3"=>"null", "video"=>"", "text"=>"Отзыв"}
  User Load (0.4ms)  SELECT  "users".* FROM "users" WHERE "users"."id" = $1 LIMIT $2  
  ↳ /home/yart/.rvm/gems/ruby-2.5.1/gems/activerecord-5.2.3/lib/active_record/log_subscriber.rb:98
  JwtBlacklist Exists (0.6ms)  SELECT  1 AS one FROM "jwt_blacklists" WHERE "jwt_blacklists"."jti" = $1 LIMIT $2  
  ↳ /home/yart/.rvm/gems/ruby-2.5.1/gems/activerecord-5.2.3/lib/active_record/log_subscriber.rb:98
Unpermitted parameter: :format
Completed 500 Internal Server Error in 4ms (ActiveRecord: 1.1ms)



ActiveSupport::MessageVerifier::InvalidSignature (ActiveSupport::MessageVerifier::InvalidSignature):

app/controllers/admin/testimonials_controller.rb:19:in `create'

Here is the model:
class Testimonial < ApplicationRecord
  has_one_attached :userpic
  has_one_attached :object_photo_1
  has_one_attached :object_photo_2
  has_one_attached :object_photo_3

  validates :name, presence: true
  validates :video, presence: true, if: Proc.new { |t| t.text.blank? }
  validates :text, presence: true, if: Proc.new { |t| t.video.blank? }
end

Here is the piece of the controller that is relevant to the question under discussion:
class Admin::TestimonialsController < ApplicationController
  before_action :authenticate_user!

# . . .

  def create
    testimonial = Testimonial.new(t_params)

    if testimonial.save
      testimonial = find_testimonial(testimonial.id)
      render json: testimonial, status: :created
    else
      render json: {errors: testimonial.errors}, status: :bad_request
    end
  end

# . . .

private

# . . .

  def t_params
    params.each { |param| param = nil if param == "null" }

    safe_params = params.permit :name, :patronymic, :surname, :userpic, :company,
                                :object_photo_1, :object_photo_2, :object_photo_3,
                                :video, :text, :id
    params = ActionController::Parameters.new(testimonial: safe_params)

    params.require(:testimonial).permit :name, :patronymic, :surname, :userpic, :company,
                                        :object_photo_1, :object_photo_2, :object_photo_3,
                                        :video, :text, :id
  end

# . . .

end

Here is what it gives as a result of its work t_params:
<ActionController::Parameters {"testimonial" => <ActionController::Parameters {
  "name" => "Иван",
  "patronymic" => "",
  "surname" => "",
  "userpic" => "",
  "company" => "",
  "object_photo_1" => #<ActionDispatch::Http::UploadedFile:0x000055cd83f1b390 @tempfile=#<Tempfile:/tmp/RackMultipart20190704-346-19rgkj4.jpg>, @original_filename="filename.jpg", @content_type="image/jpeg", @headers="Content-Disposition: form-data; name=\"object_photo_1\"; filename=\"Scan_20160802_153425.jpg\"\r\nContent-Type: image/jpeg\r\n">,
  "object_photo_2" => "null",
  "object_photo_3" => "null",
  "video" => "",
  "text" => "Отзыв"
} permitted: true>} permitted: false>

Well, the question is: at what point do I need to tear off my hands? I've already lost my feet looking for an error and trying to upload this fucking file to a server!
PS I went to the description of the MessageVerifier module. He is engaged, just, in checking the messages sent for authorization. And yet my frontend gives it away, as you can see from the headlines. Moreover, when I try to send an unauthorized request, I regularly get a 401 error.
What the InvalidSignature module does is a mystery shrouded in darkness. At least here I see only a white page with a red title:
5d1e189d565a4977044758.png
Here is a similar picture...
UPDATE
New details and details were found out, the description of which took too much space and I got out of the local limits. Therefore, I moved this description to a separate question. Well, here's what concerns this issue directly: what InvalidSignatureI did find out. Dispatched by people like me if the method verifyfrom MessageVerifierthinks that the message being processed was not signed correctly or was not Base64 encoded. And don't ask me what it all means. I also found out the reasons for this InvalidSignature: it appears when I send nullinstead of a file. The rest is here: Rails 5.2 API-mode. How to fix ActiveRecord::St...

Answer the question

In order to leave comments, you need to log in

1 answer(s)
D
Denis, 2019-07-04
@notwrite

You have an untrusted format parameter coming from somewhere. See what the browser sends with the image

Didn't find what you were looking for?

Ask your question

Ask a Question

731 491 924 answers to any question