Can't authenticate on production environment

Feature(s) impacted

Authentication in production environment

Observed behavior

image

The request is not handled by my Nginx server :


I can see an access record saved by nginx that confirm that the request is received :

[22/Feb/2023:18:34:17 +0000] "OPTIONS /forest/authentication HTTP/1.1" 204 0 "https://app.forestadmin.com/" "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:109.0) Gecko/20100101 Firefox/110.0"

And there’s an error log too :

2023/02/22 16:06:48 [error] 3015199#3015199: *5449 connect() failed (113: Unknown error) while connecting to upstream, client: <MY IP>, server: dimikev-v3.api.codingbill.com, request: "GET /forest HTTP/1.1", upstream: "http://172.17.0.4:3310/forest", host: "dimikev-v3.api.codingbill.com", referrer: "https://app.forestadmin.com/"

I tried to

Update my nginx configuration by adding Cors policies like so :

server {
  server_name dimikev-v3.api.codingbill.com;
  access_log  /var/log/nginx/dimikev-v3-access.log;
  error_log   /var/log/nginx/dimikev-v3-error.log;
  add_header 'Access-Control-Allow-Origin' "app.forestadmin.com" always;
  add_header 'Access-Control-Allow-Credentials' 'true' always;
  add_header 'Access-Control-Allow-Methods' 'GET, POST, PUT, DELETE, OPTIONS' always;
  add_header 'Access-Control-Allow-Headers' 'Accept,Authorization,Cache-Control,Content-Type,DNT,If-Modified-Since,Keep-Alive,Origin,User-Agent,X-Requested-With' always;

// ...... first lines of nginx.conf
}

Context

  • Project name: dimikev_back_2
  • Environment name: production
  • Agent type & version: Node js
    "@forestadmin/agent": "^1.8.2",
    "@forestadmin/datasource-mongoose": "^1.3.1",
  • Recent changes made on your end if any: First deploy to production, migration of the project dimikev_back from old express architecture to new one.

Some news : My frontend is up i’m just not able to connect to the admin panel, i get a 404 when i call /forest/authentication

Hello @bilboramix,

Can you please paste here the code you are using to integrate forest admin? Something might be missing.

Hello, thanks for reply !

After a bit of research after what you say i found this :

So i tried mountOnExpress() but it throws an undefined error.

By the way, here is my entry point (before any change) :

import express from "express";
import cors from "cors";
import morgan from "morgan";
import dotenv from "dotenv";
import { createAgent } from "@forestadmin/agent";
import { createMongooseDataSource } from "@forestadmin/datasource-mongoose";
import log from "./src/lib/log.js";
import dbConnectionHandler from "./src/db/dbConnectionHandler.js";
import formidable from "express-formidable";
import imageProcessorCustomizer from "./src/customizers/imageProcessorCustomizer.js";

import collectionStrings from "./src/db/collectionStrings.json" assert { type: "json" };

import getPageRoute from "./src/api/getPage.js";
import getItemsRoute from "./src/api/getItems.js";
import getPartnersRoute from "./src/api/getPartners.js";
import getItemRoute from "./src/api/getItem.js";

dotenv.config();

createAgent({
  authSecret: process.env.FOREST_AUTH_SECRET,
  envSecret: process.env.FOREST_ENV_SECRET,
  isProduction: process.env.NODE_ENV === "production",
})
  .addDataSource(createMongooseDataSource(dbConnectionHandler, { flattenMode: "auto" }))
  .customizeCollection(collectionStrings.items, imageProcessorCustomizer)
  .customizeCollection(collectionStrings.partner, imageProcessorCustomizer)
  .customizeCollection(collectionStrings.redirections, imageProcessorCustomizer)
  .customizeCollection(collectionStrings.pages, imageProcessorCustomizer)
  .customizeCollection(collectionStrings.contentblocks, imageProcessorCustomizer)
  .mountOnStandaloneServer(process.env.AGENT_PORT || 3000)
  .start();

const app = express();

app.use(cors());
app.use(morgan("dev"));
app.use(formidable());
app.use(getPageRoute);
app.use(getItemsRoute);
app.use(getPartnersRoute);
app.use(getItemRoute);

app.get("/", (req, res) => {
  res.status(200).json({ message: "Welcome to the new Dimikev API" });
});

app.listen(process.env.PORT || 3310, () => {
  log("[ Server On ]", "white", 4);
});

With this code, you have 2 independant servers, one listening on port 3000 (by default) and the other listening on port 3310.

If you want to use express, I suggest doing as explained in the docs:

import express from "express";
import cors from "cors";
import morgan from "morgan";
import dotenv from "dotenv";
import { createAgent } from "@forestadmin/agent";
import { createMongooseDataSource } from "@forestadmin/datasource-mongoose";
import log from "./src/lib/log.js";
import dbConnectionHandler from "./src/db/dbConnectionHandler.js";
import formidable from "express-formidable";
import imageProcessorCustomizer from "./src/customizers/imageProcessorCustomizer.js";

import collectionStrings from "./src/db/collectionStrings.json" assert { type: "json" };

import getPageRoute from "./src/api/getPage.js";
import getItemsRoute from "./src/api/getItems.js";
import getPartnersRoute from "./src/api/getPartners.js";
import getItemRoute from "./src/api/getItem.js";

dotenv.config();

createAgent({
  authSecret: process.env.FOREST_AUTH_SECRET,
  envSecret: process.env.FOREST_ENV_SECRET,
  isProduction: process.env.NODE_ENV === "production",
})
  .addDataSource(createMongooseDataSource(dbConnectionHandler, { flattenMode: "auto" }))
  .customizeCollection(collectionStrings.items, imageProcessorCustomizer)
  .customizeCollection(collectionStrings.partner, imageProcessorCustomizer)
  .customizeCollection(collectionStrings.redirections, imageProcessorCustomizer)
  .customizeCollection(collectionStrings.pages, imageProcessorCustomizer)
  .customizeCollection(collectionStrings.contentblocks, imageProcessorCustomizer);

const app = express();

// This function must be called before other middlewares.
agent.mountOnExpress(app).start();

app.use(cors());
app.use(morgan("dev"));
app.use(formidable());
app.use(getPageRoute);
app.use(getItemsRoute);
app.use(getPartnersRoute);
app.use(getItemRoute);

app.get("/", (req, res) => {
  res.status(200).json({ message: "Welcome to the new Dimikev API" });
});

app.listen(process.env.PORT || 3310, () => {
  log("[ Server On ]", "white", 4);
});

What kind of error do you have if you proceed with this code?

Okay i needed to unmount first :

const agent = createAgent({
  authSecret: process.env.FOREST_AUTH_SECRET,
  envSecret: process.env.FOREST_ENV_SECRET,
  isProduction: process.env.NODE_ENV === "production",
})
  .addDataSource(createMongooseDataSource(dbConnectionHandler, { flattenMode: "auto" }))
  .customizeCollection(collectionStrings.items, imageProcessorCustomizer)
  .customizeCollection(collectionStrings.partner, imageProcessorCustomizer)
  .customizeCollection(collectionStrings.redirections, imageProcessorCustomizer)
  .customizeCollection(collectionStrings.pages, imageProcessorCustomizer)
  .customizeCollection(collectionStrings.contentblocks, imageProcessorCustomizer);
// .mountOnStandaloneServer(process.env.AGENT_PORT || 3000)
// .start();

const app = express();
agent.mountOnExpress(app).start();

If agent is already mounted this is throwing with undefined.

Seems to work, gonna push this and try to authenticate, i’ll let you know.

1 Like

It works ! Thank you so much. I believe that i merged few docs parts together when i did the boilerplate code…

My first concern should be push to production tho…

1 Like