What cause 'Can't verify CSRF token authenticity' and '422' errors on upload image with dropzone JS?
Asked Answered
P

0

0

Working on app for months that has few models accept image upload with dropzone JS using ActiveStorage, and out of no where I can't upload images anymore using dropzone anymore. The only thing I know I changed across the app is changed view engine from ERB to HAML. Could that cause the issue.?

I spent hours searching for a solution, but nothing works. Here is the app error when I attempt to upload an image.

Error creating Blob for "image_name.jpg". Status: 422

And here is terminal log:

Started GET "/rails/active_storage/disk/eyJfcmFpbHMiOnsibWVzc2FnZSI6IkJBaDdDVG9JYTJWNVNTSWhkemx3TjNKMU5teDNhRzQxYzI1bU9YWnBZM1ZzTVRCMk1ua3hOUVk2QmtWVU9oQmthWE53YjNOcGRHbHZia2tpQVl4cGJteHBibVU3SUdacGJHVnVZVzFsUFNJeU1ESXdNRFV3TmpFNE1URXhPUzA1TW1NNU9HRmpaV1ExTW1SaE56UXlZelkyWldWbU4yUTFZMlV6TkdabU55NXFjR2NpT3lCbWFXeGxibUZ0WlNvOVZWUkdMVGduSnpJd01qQXdOVEEyTVRneE1URTVMVGt5WXprNFlXTmxaRFV5WkdFM05ESmpOalpsWldZM1pEVmpaVE0wWm1ZM0xtcHdad1k3QmxRNkVXTnZiblJsYm5SZmRIbHdaVWtpRDJsdFlXZGxMMnB3WldjR093WlVPaEZ6WlhKMmFXTmxYMjVoYldVNkNteHZZMkZzIiwiZXhwIjoiMjAyMS0wMy0yNlQxOTo1Nzo0MS4yMDRaIiwicHVyIjoiYmxvYl9rZXkifX0=--45a242e52828942cb9933781663d53482286244d/20200506181119-92c98aced52da742c66eef7d5ce34ff7.jpg" for ::1 at 2021-03-26 23:52:42 +0400


Processing by ActiveStorage::DiskController#show as JPEG
Parameters: {"encoded_key"=>"[FILTERED]", "filename"=>"20200506181119-92c98aced52da742c66eef7d5ce34ff7"}
Completed 200 OK in 1ms (ActiveRecord: 0.0ms | Allocations: 471)

Started POST "/rails/active_storage/direct_uploads" for ::1 at 2021-03-27 05:21:48 +0400
Processing by ActiveStorage::DirectUploadsController#create as JSON
Parameters: {"blob"=>{"filename"=>"88a04c2e5f589fcebda2641d00b8427f.jpg", "content_type"=>"image/jpeg", "byte_size"=>511762, "checksum"=>"y/nNLQR9mGaB5haUie2M5Q=="}, "direct_upload"=>{"blob"=>{"filename"=>"88a04c2e5f589fcebda2641d00b8427f.jpg", "content_type"=>"image/jpeg", "byte_size"=>511762, "checksum"=>"y/nNLQR9mGaB5haUie2M5Q=="}}}


Can't verify CSRF token authenticity.
Completed 422 Unprocessable Entity in 2ms (ActiveRecord: 0.0ms | Allocations: 1029)


ActionController::InvalidAuthenticityToken - ActionController::InvalidAuthenticityToken:

I'm using Rails6, and ruby 3. No calling API involve at this stage. I noticed that uploading images with dropzone JS cause this issue. And upload without dropzone JS works fine. What could be the cause?

Here is console error:

dropzone.js:8185 Uncaught TypeError: Cannot read property 'apply' of undefined
        at Dropzone.emit (dropzone.js:8185)
        at dropzone.js:10197
        at dropzone.js:10423
        at loadExif (dropzone.js:10346)
        at HTMLImageElement.img.onload (dropzone.js:10357)
    emit @ dropzone.js:8185
    (anonymous) @ dropzone.js:10197
    (anonymous) @ dropzone.js:10423
    loadExif @ dropzone.js:10346
    img.onload @ dropzone.js:10357
    load (async)
    createThumbnailFromUrl @ dropzone.js:10344
    fileReader.onload @ dropzone.js:10294
    load (async)
    createThumbnail @ dropzone.js:10283
    _processThumbnailQueue @ dropzone.js:10196
    (anonymous) @ dropzone.js:10179
    setTimeout (async)
    _enqueueThumbnail @ dropzone.js:10178
    addFile @ dropzone.js:10113
    (anonymous) @ dropzone.js:9533
    activestorage.js:739 POST 

http://localhost:5000/rails/active_storage/direct_uploads 422 (Unprocessable Entity)
    create @ activestorage.js:739
    (anonymous) @ activestorage.js:873
    fileReaderDidLoad @ activestorage.js:620
    (anonymous) @ activestorage.js:605
    load (async)
    create @ activestorage.js:604
    create @ activestorage.js:584
    create @ activestorage.js:865
    start @ dropzone_controller.js:93
    (anonymous) @ dropzone_controller.js:31
    setTimeout (async)
    (anonymous) @ dropzone_controller.js:30
    emit @ dropzone.js:8185
    addFile @ dropzone.js:10111
    (anonymous) @ dropzone.js:9533

UPDATE

Here is my dropzone_controller.js file with stimulus

import { Controller } from "stimulus";
import Dropzone from "dropzone";
import "dropzone/dist/min/dropzone.min.css";
import "dropzone/dist/min/basic.min.css";
import { DirectUpload } from "@rails/activestorage";

export default class extends Controller {
    static targets = ["input"];

    connect() {
        Dropzone.autoDiscover = false;
        this.inputTarget.disable = true;
        this.inputTarget.style.display = "none";
        const dropzone = new Dropzone(this.element, {
            url: "/",
            maxFiles: "10",
            maxFilesize: "10",
        });


        dropzone.on("addedfile", (file) => {
            setTimeout(() => {
                if (file.accepted) {
                    const upload = new DirectUpload(file, this.url);
                    upload.create((error, attributes) => {
                        this.hiddenInput = document.createElement("input");
                        this.hiddenInput.type = "hidden";
                        this.hiddenInput.name = this.inputTarget.name;
                        this.hiddenInput.value = attributes.signed_id; << error here
                        this.inputTarget.parentNode.insertBefore(
                            this.hiddenInput,
                            this.inputTarget.nextSibling
                        );
                        dropzone.emit("success", file);
                        dropzone.emit("complete", file);
                    });
                }
            }, 500);
        });
    }

    get url() {
        return this.inputTarget.getAttribute("data-direct-upload-url");
    }
}

When I attempt to upload an image, an error related to blob shows up. Uncaught TypeError: can't access property "signed_id", blob is undefined

Perrin answered 27/3, 2021 at 1:36 Comment(4)
When using rails' methods to submit forms with JS (like remote: true) it internally adds the CSRF token to the request's headershttps://github.com/rails/rails/blob/main/actionview/app/assets/javascripts/rails-ujs/utils/csrf.coffee. You'll have to hook into Dropzone's request callbacks to add the token with a similar code. #30149523Freytag
Does this answer your question? How to include the CSRF token in the headers in Dropzone upload request?Freytag
@Freytag Sadly it doesn't it. Still have same error.Perrin
Possibly related here. For me, it helped to give an authenticityToken from the controller to the frontend and just give that back to the backend unchanged when the request is done.Linen

© 2022 - 2024 — McMap. All rights reserved.