Search code examples
reactjsauthenticationreduxaccess-tokenfine-uploader

react-fine-uploader to authenticate in the backend with redux-token-auth


In my stack I am using redux-token-auth to authenticate users with my rails backend (devise_token_auth). In my app I need to allow authenticated users to upload images, for this I'm using react-fine-uploader.

My problem is that I'm not seeing a way to have ract-fine-uploader to POST the images in an authenticated way. and in general how to use redux-token-auth to upload data to my backend with authentication.

I found that redux-token-auth stores authentication tokens in the localStorage, so I'm kinda able to retrieve it and authenticate my requests. Though I don't like accessing such data directly with a localStorage.get("access-token") (It's written by the package, it just seems fair to use the package to handle it).

Also with react-fine-uploader the response object doesn't contain the headers from the server response, so I'm not sure on how to get the new tokens to store them.

Here's the code I got so far:

my ImagesUploader:

import React from "react";
import PropTypes from "prop-types";

import FineUploaderTraditional from "fine-uploader-wrappers";
import Gallery from "react-fine-uploader";
import { backend } from "../../libs/itemTools";
import "react-fine-uploader/gallery/gallery.css";

const ImagesUploader = props => {
  const uploader = new FineUploaderTraditional({
    options: {
      multiple: false,
      validation: {
        itemLimit: 1
      },
      request: {
        endpoint: backend.createImage,
        customHeaders: {
          "access-token": localStorage.getItem("access-token"),
          "token-type": localStorage.getItem("token-type"),
          client: localStorage.getItem("client"),
          uid: localStorage.getItem("uid")
        }
      },
      session: {
        endpoint: backend.loadImages(props.itemId)
      },
      deleteFile: {
        enabled: true,
        endpoint: backend.deleteImage(props.itemId)
      },
      cors: {
        expected: true
      },
      callbacks: {
        onComplete: (id, name, response, xhr) => {
          if (response.success) {
            response.image.id;
            //TODO save new access-token 
            // #######     THIS DOESN'T work, #########
            //fine-uploader doesn't include headers in the response object. 
            localStorage.setItem("access-token", response.headers["access-token"]);
            localStorage.setItem("token-type", response.headers("token-type"));
            localStorage.setItem("client", response.headers(client));
            localStorage.setItem("uid", response.headers(uid));
          } else {
            // [...]
          }
        },
        onSessionRequestComplete: (...params) => {
          console.log(
            "onSessionRequestComplete: " + JSON.stringify(params, 0, 2)
          );
        }
      }
    }
  });

  return (
    <div id="upload-area">
      <Gallery uploader={uploader} />
    </div>
  );
};

ImagesUploader.propTypes = {
  userId: PropTypes.number.isRequired,
  itemId: PropTypes.number.isRequired
};

export default ImagesUploader;

It seems strange to me that redux-token-auth packages doesn't account for authenticated backend calls, and that fine-uploader doesn't give access to the response headers..

Is there maybe something I'm missing?


Solution

  • From taking a look at redux-token-auth, it expects to handle all auth calls and doesn't give you an escape hatch in the code - so yanking the localstorage seems like a prudent thing to do there. You can see in the code that it sets it for every request: https://github.com/kylecorbelli/redux-token-auth/blob/8c5a8fe573918d406a733ca1b21c0b4349f137ab/src/actions.ts#L160

    As for fine-uploader it looks like you can grab the rawheaders by using xhr.response https://github.com/FineUploader/fine-uploader/blob/master/client/js/traditional/traditional.xhr.upload.handler.js#L59

    The response variable that you get back has been JSON parsed via the qq variable you pass in: https://github.com/FineUploader/fine-uploader/blob/master/client/js/traditional/traditional.xhr.upload.handler.js#L109