title: React Hooks/Next.js and Multer: 401 Unauthorized, Error while uploading image to MongoDB Atlas
body: <p>I've tried numerous configurations and been pulling my hair out for a couple days now. However no matter what I do when I try to hit <code>/users/uploadmulter</code> I get an authorized error. </p>
  
  <p>On mongoDB atlas I've tried creating a new collection.</p>
  
  <p>Moving the route declaration in my users file (that way I know it's not an express config issue as other operations work i.e. make a user, get new password etc.)</p>
  
  <p>Anyway, here is my React component:</p>
  
  <pre><code>import { useState, useEffect } from 'react';
  
  import { Card, Icon, Image, Segment, Form } from 'semantic-ui-react';
  
  import axios from 'axios';
  
  function ImageUploader() {
    var [defaultImage, setDefaultImage] = useState(
      require('../../assets/images/placeholder.jpg')
    );
    var [userAvatar, setUserAvatar] = useState(defaultImage);
  
    useEffect(() =&gt; {
      setUserAvatar(userAvatar);
    }, [userAvatar]);
  
    function fileUploader(e) {
      console.log('event fileUploader ', e);
      var imageFormObj = new FormData();
  
      console.log('e.target.files[0] ', e.target.files[0]);
  
      imageFormObj.append('avatar', 'multer-image-' + Date.now());
      imageFormObj.append('imageData', e.target.files[0]);
      setUserAvatar(URL.createObjectURL(e.target.files[0]));
  
      console.log('userAvatar ', userAvatar);
      console.log('imageFormObj ', imageFormObj);
  
      axios
        .post('http://localhost:8016/users/uploadmulter', imageFormObj)
        .then(data =&gt; {
          if (data.data.success) {
            alert('Image has been successfully uploaded using multer');
          }
        })
        .catch(err =&gt; {
          alert('Error while uploading image using multer');
        });
    }
  
    return (
      &lt;&gt;
        &lt;Segment&gt;
          &lt;Card fluid&gt;
            &lt;Image src={userAvatar} alt="upload-image" /&gt;
            &lt;Segment&gt;
              &lt;Form encType="multipart/form-data"&gt;
                &lt;Form.Field&gt;
                  &lt;input
                    placeholder="Name of image"
                    className="process__upload-btn"
                    type="file"
                    name="avatar"
                    content="Edit your Avatar!"
                    onChange={e =&gt; fileUploader(e)}
                  /&gt;
                  {/* &lt;Button
                    content="Edit your Avatar!"
                    labelPosition="left"
                    icon="file"
                    onClick={e =&gt; fileUploader(e)}
                  /&gt; */}
                &lt;/Form.Field&gt;
              &lt;/Form&gt;
            &lt;/Segment&gt;
            &lt;Card.Content&gt;
              &lt;Card.Header&gt;Charly&lt;/Card.Header&gt;
              &lt;Card.Meta&gt;
                &lt;span className="date"&gt;Joined in 2015&lt;/span&gt;
              &lt;/Card.Meta&gt;
              &lt;Card.Description&gt;Charly&lt;/Card.Description&gt;
            &lt;/Card.Content&gt;
            &lt;Card.Content extra&gt;
              &lt;a&gt;
                &lt;Icon name="user" /&gt;
                22 Friends
              &lt;/a&gt;
            &lt;/Card.Content&gt;
          &lt;/Card&gt;
        &lt;/Segment&gt;
      &lt;/&gt;
    );
  }
  
  export default ImageUploader;
  </code></pre>
  
  <p>And this is my route which handles sending the data to MongoDB Atlas:</p>
  
  <pre><code>var router = require('express').Router();
  var Image = require('../models/UserImagesSchema');
  var multer = require('multer');
  
    var storage = multer.diskStorage({
    destination: function(req, file, cb) {
      cb(null, './uploads/');
    },
    filename: function(req, file, cb) {
      cb(null, Date.now() + file.originalname);
    }
  });
  
  var upload = multer({
    storage: storage,
    limits: {
      fileSize: 1024 * 1024 * 5
    }
  });
  
  /*
  stores image in uploads folder
  using mulkter and creates a reference to the file
  */
  
  router.post(upload.single('imageData'), (req, res, next) =&gt; {
    console.log(req.body);
    var newImage = new Image({
      avatar: {
        imageName: req.body.avatar,
        imageData: req.file.path
      }
    });
  
    newImage
      .save()
      .then(result =&gt; {
        console.log(result);
        res.status(200).json({
          success: true,
          document: result
        });
      })
      .catch(err =&gt; next(err));
  });
  
  module.exports = router;
  </code></pre>
  
  <p>This is my Schema:</p>
  
  <pre><code>var mongoose = require('mongoose');
  
  /* Image Schema for storing images in the mongodb database */
  
  var UserImagesSchema = new mongoose.Schema({
    avatar: {
      _userId: { type: mongoose.Schema.Types.ObjectId, required: true, ref: 'User' },
      imageName: { type: String, default: 'none', required: true },
      imageData: {
        data: Buffer,
        contentType: String
      }
    }
  });
  
  module.exports = mongoose.model('UserImages', UserImagesSchema);
  </code></pre>
  
  <p>This is the app/server file for express:</p>
  
  <pre><code>var express = require('express');
  
  require('dotenv').config();
  var path = require('path');
  var morgan = require('morgan');
  var cookieParser = require('cookie-parser');
  var cors = require('cors');
  
  var nextJS = require('next');
  var session = require('express-session');
  var MongoStore = require('connect-mongo')(session);
  var bodyParser = require('body-parser');
  var auth = require('./lib/auth');
  var HttpStatus = require('http-status-codes');
  var compression = require('compression');
  var helmet = require('helmet');
  
  var PORT = process.env.PORT || 8016;
  
  var { isBlockedPage, isInternalUrl } = require('next-server/dist/server/utils');
  
  function NODE_ENVSetter(ENV) {
    var environment,
      environments = {
        production: () =&gt; {
          environment = process.env.MONGODB_URI;
          console.log(`We are currently in the production environment: ${environment}`);
          return environment;
        },
        test: () =&gt; {
          environment = process.env.TEST_DB_DSN;
          console.log(`We are currently in the test environment: ${environment}`);
          return environment;
        },
        default: () =&gt; {
          environment = process.env.DEVELOPMENT_DB_DSN;
          console.log(`We are currently in the development environment: ${environment}`);
          return environment;
        }
      };
    (environments[ENV] || environments['default'])();
  
    return environment;
  }
  
  var db = NODE_ENVSetter('development');
  var mongoose = require('mongoose');
  
  function errorHandler(err, req, res, next) {
    // Set locals, only providing error in development
    res.locals.message = err.message;
    res.locals.error = req.app.get('env') === 'development' ? err : {};
  
    // Log error
    console.error(err.stack);
  
    // Render the error page
    res.status(err.status || 500);
  
    // Default error message by HTTP code
    res.render('error', {
      title: HttpStatus.getStatusText(err.status),
      message: HttpStatus.getStatusText(err.status)
    });
  }
  
  function start() {
    const dev = process.env.NODE_ENV !== 'production';
    const app = nextJS({ dev });
    const server = express();
    // const proxy = createProxyMiddleware(options);
  
    app
      .prepare()
      .then(() =&gt; {
        mongoose.connect(db, { useNewUrlParser: true, useUnifiedTopology: true });
        mongoose.Promise = global.Promise;
  
        mongoose.connection
          .on('connected', () =&gt; {
            console.log(`Mongoose connection open on ${db}`);
          })
          .on('error', err =&gt; {
            console.log(`Connection error: ${err.message}`);
          });
      })
      .catch(err =&gt; {
        console.error(err);
      });
  
    server.use(
      session({
        secret: 'very secret 12345',
        resave: false,
        saveUninitialized: false,
        store: new MongoStore({ mongooseConnection: mongoose.connection })
      })
    );
  
    server.use((req, res, next) =&gt; {
      res.setHeader('Access-Control-Allow-Origin', '*');
      res.header(
        'Access-Control-Allow-Headers',
        'Origin, X-Requested-With, Content-Type, Accept'
      );
      res.header('Access-Control-Allow-Credentials', true);
      res.header('Access-Control-Allow-Methods', '*'); // enables all the methods to take place
      return next();
    });
  
    server.set('view engine', 'html');
    server.use(cors());
  
    server.use(morgan('dev'));
    server.use('/uploads', express.static('uploads'));
    server.use(bodyParser.json({ limit: '50mb' }));
    server.use(bodyParser.urlencoded({ limit: '50mb', extended: true }));
    server.use(cookieParser());
    server.use(express.static(path.join(__dirname + 'uploads')));
  
    server.use(compression());
    server.use(helmet());
    server.use(auth.initialize);
    server.use(auth.session);
    server.use(auth.setUser);
    // console.log('auth.setUser ', auth.setUser);
  
    server.use('/users', require('./users'));
  
    // Redirect all requests to main entrypoint pages/index.js
    server.get('/*', async (req, res, next) =&gt; {
      try {
        // @NOTE code duplication from here
        // https://github.com/zeit/next.js/blob/cc6fe5fdf92c9c618a739128fbd5192a6d397afa/packages/next-server/server/next-server.ts#L405
        const pathName = req.originalUrl;
        if (isInternalUrl(req.url)) {
          return app.handleRequest(req, res, req.originalUrl);
        }
  
        if (isBlockedPage(pathName)) {
          return app.render404(req, res, req.originalUrl);
        }
  
        // Provide react-router static router with a context object
        // https://reacttraining.com/react-router/web/guides/server-rendering
        req.locals = {};
        req.locals.context = {};
        const html = await app.renderToHTML(req, res, '/', {});
  
        // Handle client redirects
        const context = req.locals.context;
        if (context.url) {
          return res.redirect(context.url);
        }
  
        // Handle client response statuses
        if (context.status) {
          return res.status(context.status).send();
        }
  
        // Request was ended by the user
        if (html === null) {
          return;
        }
  
        app.sendHTML(req, res, html);
      } catch (e) {
        next(e);
      }
    });
  
    // catch 404 and forward to error handler
    server.use(function(req, res, next) {
      next(createError(404));
    });
  
    // error handler
    server.use(function(err, req, res, next) {
      // set locals, only providing error in development
      res.locals.errorStatus = err.status;
      res.locals.errorMessage = err.message;
      res.locals.error = req.app.get('env') === 'development' ? err : {};
      console.log('err.status ', err.status);
      res.status(401).send(err.message);
    });
  
    if (process.env.NODE_ENV === 'production') {
      server.use(express.static('.next/static'));
  
      server.get('*', (req, res) =&gt; {
        res.sendFile(path.resolve(__dirname, '.next/static', 'index.html'));
      });
  
      server.listen(PORT, err =&gt; {
        if (err) throw err;
        console.log(
          `&gt; Ready and listening on PORT:${PORT} in the ${process.env.NODE_ENV} environment`
        );
      });
    } else {
      server.listen(PORT, err =&gt; {
        if (err) throw err;
        console.log(`&gt; Ready and listening on http://localhost:${PORT}`);
      });
    }
  }
  
  start();
  </code></pre>