Home > Blockchain >  mongoDB database exposed on /api, how do I hide this?
mongoDB database exposed on /api, how do I hide this?

Time:10-15

I'm using a mongoDB database, Vue, axios, caddy server and nodejs.

I followed this tutorial: https://www.youtube.com/watch?v=ek50iuo5zkE&ab_channel=DesignCourse which has resulted in my entire database being exposed in JSON on example.com/api. For example, the first line of the page could be:

[{"_id":"6168115af6bfc986c18f821d","name":"test","age":"20","__v":0},

It lists the entire database. How do I hide this?

My app.js file, as in the tutorial is:

let express = require('express'),
  cors = require('cors'),
  mongoose = require('mongoose'),
  database = require('./database'),
  bodyParser = require('body-parser');


//connect mongoDB
mongoose.Promise = global.Promise;
mongoose.connect(database.db, {
  useNewUrlParser: true,
  useUnifiedTopology: true
}).then(() => {
  console.log("Database connected")
  },
  error => {
    console.log("Database couldn't be connected to: "   error);
  }
)

const cryptoEndPoint = require('../backend/routes/crypto.route')
const app = express();
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({
  extended: false
}));
app.use(cors())

//API
app.use('/api', cryptoEndPoint)

//create port
const port = process.env.PORT || 4000;
const server = app.listen(port, () => {
  console.log('Connected to port '   port);
})

//Find 404
app.use((req, res, next) => {
  next(createError(404));
})

//error handler
app.use(function (err, req, res, next) {
  console.log(err.message);
  if (!err.statusCode) err.statusCode = 500;
  res.status(err.statusCode).send(err.message);
})

.env.development file:

VUE_APP_BASE_API_URL=http://localhost:4000/api

.env.production file:

VUE_APP_BASE_API_URL=https://example.com/api

database.js file:

module.exports = {
  db: process.env.MONGO_CONNECTION_URI
}

I thought this might be a caddy (server) issue, but I posted on their forum and they said it was a node issue, and "You should be reverse_proxying to your NodeJS app, not to your database." I was under the impression my caddy server was doing this already, my caddy file is:

example.com {
        handle /api* {
                reverse_proxy localhost:4000
        }

        handle {
                root * /var/www/html
                try_files {path} /index.html
                file_server
        }
}

From the tutorial, I also have crypto.route.js:

const express = require('express');
const cryptoRoute = express.Router();

let CryptoModel = require('../models/Crypto');

cryptoRoute.route('/').get((req, res) => {
  CryptoModel.find((error, data) => {
    if (error) {
      return next(error)
    } else {
      res.json(data)
    }
  })
})

cryptoRoute.route('/add-crypto').post((req, res, next) => {
  CryptoModel.create(req.body, (error, data) => {
    if (error) {
      return next(error)
    } else {
      res.json(data)
    }
  })
})

Crypto.js:

const mongoose = require('mongoose');
const Schema = mongoose.Schema;

let cryptoSchema = new Schema({
  name: {
    type: String
  }
}, {
  collection: 'sentences_nouns'
})

module.exports = mongoose.model('Crypto', cryptoSchema);

CodePudding user response:

cryptoRoute.route('/').get((req, res) => {
  CryptoModel.find((error, data) => {
    ...

GET on your /api route returns your whole DB because you don't using any query in get method. The simplest way to avoid it is to add some parameters to the endpont e.g. /api/:id, then get that parameter and put in query

cryptoRoute.route('/:id').get((req, res) => {
  const urlId = req.params.id
  CryptoModel.find({ id: urlId }, (error, data) => {
     ...

I would recommended to read about routing in express and queries in mongoose

CodePudding user response:

Do you mean you want to hide some properties of a document? if so you should use projection in mongoose and specify the fields you want.

cryptoRoute.route('/').get((req, res) => {
  CryptoModel.find((error, data) => {
    if (error) {
      return next(error)
    } else {
      res.json(data.projection({ name: 1 }))
    }
  })
})

so in this snippet, we choose just name field

follow this link: "projection in mongoose" mongodb

  • Related