Имею Nuxt/Rails приложение. Надо с фронта отправить картинку на бэкенд. Делаю следующим образом:
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 + ''
})
}
Вот заголовки, которые формируются при отработке метода:
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: Отзыв
Сервер плюётся пятисотой ошибкой:
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 [["id", 1], ["LIMIT", 1]]
↳ /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 [["jti", "c4cf865b-5191-4946-8a87-472fcc73c094"], ["LIMIT", 1]]
↳ /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'
Вот модель:
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
Вот кусок контроллера, который имеет отношение к обсуждаемому вопросу:
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
Вот то, что отдаёт в результате своей работы
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>
Ну и вопрос: в какой именно момент мне надо отрывать руки? Я уже с ног сбился в поисках ошибки и в попытках отгрузить на сервак этот долбаный файл!
PS На описание модуля MessageVerifier я ходил. Он занимается, как раз, проверкой присылаемых сообщений на авторизацию. И таки фронтенд мой её отдаёт, что видно из заголовков. Более того, при попытке отправить неавторизованный запрос, я исправно получаю 401 ошибку.
Чем занимается модуль InvalidSignature — тайна, покрытая мраком. По-крайней мере
вот тут я вижу только белую страницу с красным заголовком:
Здесь аналогичная картина...
UPDATE
Выяснились новые детали и подробности, описание которых заняло слишком много места и я вылез за местные лимиты. Поэтому перенёс это описание в отдельный вопрос. Ну и вот то, что касается непосредственно данного вопроса: чем занимается
InvalidSignature
я таки выяснил. Отправляется таким как я, если метод
verify
из
MessageVerifier
считает, что обрабатываемое сообщение не было подписано правильно либо не было закодировано в Base64. И не надо меня спрашивать, что всё это значит. Я выяснил также и причины появления этого InvalidSignature: он появляется тогда, когда я отправляю
null
вместо файла. Остальное вот тут:
Rails 5.2 API-mode. Как пофиксить ActiveRecord::St...