[SOLVED] Moralis.Auth.verify 400 bad request error

I’m following the moralis tutorial to build an authentication and authorization system with moralis and reactJS. I get this error when i hit this route http://localhost:4000/verify. The code that creates this error is the following:

const { address, profileId } = (
      await Moralis.Auth.verify({
        message,
        signature,
        networkType: "evm",
      })
    ).raw;

This is the full code of the request:

const Moralis = require("moralis").default;

const express = require("express");
const cors = require("cors");
const cookieParser = require("cookie-parser");
const jwt = require("jsonwebtoken");

// to use our .env variables
require("dotenv").config();

const app = express();
const port = 4000;

app.use(express.json());
app.use(cookieParser());

// allow access to React app domain
app.use(
  cors({
    origin: "http://localhost:3000",
    credentials: true,
  })
);

const config = {
  domain: process.env.APP_DOMAIN,
  statement: "Please sign this message to confirm your identity.",
  uri: process.env.REACT_URL,
  timeout: 60,
};

app.post("/verify", async (req, res) => {
  try {
    const { message, signature } = req.body;

    const { address, profileId } = (
      await Moralis.Auth.verify({
        message,
        signature,
        networkType: "evm",
      })
    ).raw;

    const user = { address, profileId, signature };

    // create JWT token
    const token = jwt.sign(user, process.env.AUTH_SECRET);

    // set JWT cookie
    res.cookie("jwt", token, {
      httpOnly: true,
    });

    res.status(200).json(user);
  } catch (error) {
    res.status(400).json({ error: error.message });
    console.error(error);
  }
});

Full error message:

MoralisError [Moralis SDK Core Error]: [C0006] Request failed, Bad Request(400): Invalid message: {"success":false,"state":103,"length":277,"matched":0,"maxMatched":5,"maxTreeDepth":15,"nodeHits":184,"inputLength":277,"subBegin":0,"subEnd":277,"subLength":277}
    at RequestController.makeError (/Users/filippomeda/Desktop/dev/web3/income/Improver/server/node_modules/@moralisweb3/common-core/lib/cjs/index.cjs:1224:20)
    at RequestController.<anonymous> (/Users/filippomeda/Desktop/dev/web3/income/Improver/server/node_modules/@moralisweb3/common-core/lib/cjs/index.cjs:1205:38)
    at step (/Users/filippomeda/Desktop/dev/web3/income/Improver/server/node_modules/@moralisweb3/common-core/lib/cjs/index.cjs:83:23)
    at Object.throw (/Users/filippomeda/Desktop/dev/web3/income/Improver/server/node_modules/@moralisweb3/common-core/lib/cjs/index.cjs:64:53)
    at rejected (/Users/filippomeda/Desktop/dev/web3/income/Improver/server/node_modules/@moralisweb3/common-core/lib/cjs/index.cjs:55:65)
    at processTicksAndRejections (node:internal/process/task_queues:96:5) {
  isMoralisError: true,
  code: 'C0006',
  details: {
    status: 400,
    response: {
      status: 400,
      statusText: 'Bad Request',
      headers: [AxiosHeaders],
      config: [Object],
      request: [ClientRequest],
      data: [Object]
    }
  },
  [cause]: AxiosError: Request failed with status code 400
      at settle (/Users/filippomeda/Desktop/dev/web3/income/Improver/server/node_modules/axios/dist/node/axios.cjs:1909:12)
      at IncomingMessage.handleStreamEnd (/Users/filippomeda/Desktop/dev/web3/income/Improver/server/node_modules/axios/dist/node/axios.cjs:2989:11)
      at IncomingMessage.emit (node:events:539:35)
      at endReadableNT (node:internal/streams/readable:1345:12)
      at processTicksAndRejections (node:internal/process/task_queues:83:21) {
    code: 'ERR_BAD_REQUEST',
    config: {
      transitional: [Object],
      adapter: [Array],
      transformRequest: [Array],
      transformResponse: [Array],
      timeout: 20000,
      xsrfCookieName: 'XSRF-TOKEN',
      xsrfHeaderName: 'X-XSRF-TOKEN',
      maxContentLength: Infinity,
      maxBodyLength: Infinity,
      env: [Object],
      validateStatus: [Function: validateStatus],
      headers: [AxiosHeaders],
      method: 'post',
      url: 'https://authapi.moralis.io/challenge/verify/evm',
      params: {},
      data: '{"message":"http://localhost:3000 wants you to sign in with your Ethereum account:\\n0xa9B54220AD207Cf6fffb587493ff774c6d763706\\n\\nPlease sign this message to confirm your identity.\\n\\nURI: http://localhost:3000\\nVersion: 1\\nChain ID: 1\\nNonce: Qk1yAs9wQ9u1It47Q\\nIssued At: 2023-07-17T12:10:57.277Z","signature":"0x2a47b5edf79b27eab4638e8ac86696ab60628b43f4bf11f0323f697f8eeda384327c13cf6e94171552920f5043e062244a29e16b152bcc1dee8f91c53bd0030b1c"}'
    },
    request: ClientRequest {
      _events: [Object: null prototype],
      _eventsCount: 7,
      _maxListeners: undefined,
      outputData: [],
      outputSize: 0,
      writable: true,
      destroyed: false,
      _last: true,
      chunkedEncoding: false,
      shouldKeepAlive: false,
      maxRequestsOnConnectionReached: false,
      _defaultKeepAlive: true,
      useChunkedEncodingByDefault: true,
      sendDate: false,
      _removedConnection: false,
      _removedContLen: false,
      _removedTE: false,
      _contentLength: null,
      _hasBody: true,
      _trailer: '',
      finished: true,
      _headerSent: true,
      _closed: false,
      socket: [TLSSocket],
      _header: 'POST /challenge/verify/evm HTTP/1.1\r\n' +
        'Accept: application/json, text/plain, */*\r\n' +
        'Content-Type: application/json\r\n' +
        'x-moralis-platform: NodeJS SDK\r\n' +
        'x-moralis-platform-version: 2.22.4\r\n' +
        'x-moralis-build-target: node\r\n' +
        'x-api-key:nokeysharing\r\n' +
        'User-Agent: axios/1.4.0\r\n' +
        'Content-Length: 447\r\n' +
        'Accept-Encoding: gzip, compress, deflate, br\r\n' +
        'Host: authapi.moralis.io\r\n' +
        'Connection: close\r\n' +
        '\r\n',
      _keepAliveTimeout: 0,
      _onPendingData: [Function: nop],
      agent: [Agent],
      socketPath: undefined,
      method: 'POST',
      maxHeaderSize: undefined,
      insecureHTTPParser: undefined,
      path: '/challenge/verify/evm',
      _ended: true,
      res: [IncomingMessage],
      aborted: false,
      timeoutCb: null,
      upgradeOrConnect: false,
      parser: null,
      maxHeadersCount: null,
      reusedSocket: false,
      host: 'authapi.moralis.io',
      protocol: 'https:',
      _redirectable: [Writable],
      [Symbol(kCapture)]: false,
      [Symbol(kNeedDrain)]: false,
      [Symbol(corked)]: 0,
      [Symbol(kOutHeaders)]: [Object: null prototype]
    },
    response: {
      status: 400,
      statusText: 'Bad Request',
      headers: [AxiosHeaders],
      config: [Object],
      request: [ClientRequest],
      data: [Object]
    }
  }
}

If you have any suggestion please let me know it.

Hi @Shadq

Did you get any other error logs in your code editor console? More details about the error might help to debug further.

Since the error happened at /verify a possible cause for the error can be incorrect message, signature params sent from frontend code

i just added the full error message

Thanks, The error message says, Invalid message so the message value which is sent from front end code must be wrong.

Please check you frontend code and verify if you are sending the correct message value to the /verify endpoint.

1 Like

I’m using the exact code for the frontend and the server of the documentation: https://docs.moralis.io/authentication-api/evm/how-to-authenticate-users-with-metamask-using-react
The code in the documentation and mine are the same.
Documentation (frontend):

import { useNavigate } from "react-router-dom";

import { useAccount, useConnect, useSignMessage, useDisconnect } from "wagmi";
import { InjectedConnector } from "wagmi/connectors/injected";
import axios from "axios";

export default function SignIn() {
  const navigate = useNavigate();

  const { connectAsync } = useConnect();
  const { disconnectAsync } = useDisconnect();
  const { isConnected } = useAccount();
  const { signMessageAsync } = useSignMessage();

  const handleAuth = async () => {
    //disconnects the web3 provider if it's already active
    if (isConnected) {
      await disconnectAsync();
    }
    // enabling the web3 provider metamask
    const { account } = await connectAsync({
      connector: new InjectedConnector(),
    });

    const userData = { address: account, chain: 1 };
    // making a post request to our 'request-message' endpoint
    const { data } = await axios.post(
      `${process.env.REACT_APP_SERVER_URL}/request-message`,
      userData,
      {
        headers: {
          "content-type": "application/json",
        },
      }
    );
    const message = data.message;
    // signing the received message via metamask
    const signature = await signMessageAsync({ message });

    await axios.post(
      `${process.env.REACT_APP_SERVER_URL}/verify`,
      {
        message,
        signature,
      },
      { withCredentials: true } // set cookie from Express server
    );

    // redirect to /user
    navigate("/user");
  };

}

My code (frontend):

import { useNavigate } from "react-router-dom";

import { useAccount, useConnect, useSignMessage, useDisconnect } from "wagmi";
import { InjectedConnector } from "wagmi/connectors/injected";
import axios from "axios";

export default function SignIn() {
  const navigate = useNavigate();

  const { connectAsync } = useConnect();
  const { disconnectAsync } = useDisconnect();
  const { isConnected } = useAccount();
  const { signMessageAsync } = useSignMessage();

  const handleAuth = async () => {
    //disconnects the web3 provider if it's already active
    if (isConnected) {
      await disconnectAsync();
    }
    // enabling the web3 provider metamask
    const { account } = await connectAsync({
      connector: new InjectedConnector(),
    });

    const userData = { address: account, chain: 1 };
    // making a post request to our 'request-message' endpoint
    const { data } = await axios.post(
      `http://localhost:4000/request-message`,
      userData,
      {
        headers: {
          "content-type": "application/json",
        },
      }
    );
    const message = data.message;
    // signing the received message via metamask
    const signature = await signMessageAsync({ message });

    await axios.post(
      `http://localhost:4000/verify`,
      {
        message,
        signature,
      },
      { withCredentials: true } // set cookie from Express server
    );

    // redirect to /user
    navigate("/user");
  };

Can you share the request payload of /verify endpoint from your browser network tab?

  1. message: “http://localhost:3000 wants you to sign in with your Ethereum account:\n0xBe06cdDda357cB8EE2B0F94e8499796A8215a1Ef\n\nPlease sign this message to confirm your identity.\n\nURI: http://localhost:3000\nVersion: 1\nChain ID: 1\nNonce: u3tStv1hewavxQOp0\nIssued At: 2023-07-17T13:23:10.669Z”
  2. signature: “0x2a2c095bf6e8052338edc4dd2c6bf62b160f02cfd91b98c43b86fee50c217c5018c390b8dd5462fdefa2e386827a6fd35873bd07d244a2a96caafbabc84e464a1b”

Are you signing the message using the same wallet whose address is mentioned in the request?

yes i am, im using the same one

Ok, Let me try running code from docs to check if I can reproduce the same error.

If you can share your code through github that would help to check if you are missing anything.

This is the link to the github repo: https://github.com/Shadq/moralis-auth-app
The file were the backend operation are made is index.js and its on the root folder not on the src one

1 Like

I was able to run your code without any errors :smile:

All I did is install the packages, added env variables, and ran the app.

these are my env variables apart from API key and auth secret.

APP_DOMAIN = localhost
REACT_URL = http://localhost:3000

In case if you have multiple address accounts in your wallet, try disconnecting all the wallets and try to login again. Also remove the previous page cache.

1 Like

fixed the problem it was the APP_DOMAIN that was set like this http://localhost:3000 instead of localhost

2 Likes