1

Client Side Browser:

API

class API {

    constructor() {

        this.api = "http://localhost:3000";
    }

    async authenticate(product_id) {

        const url = this.api + '/api/auth';
        const body = {
            "product_id": product_id,
        }

        console.log(body);

        const request = {
            method: 'POST',
            body: body,
        }
        return await fetch(url, request);
    }
}

module.exports = API;

INDEX

const account = await this.API.authenticate("56729b6b77c82288f746c0cf");

console.log(account)

In my console i get

Response {type: "cors", url: "http://localhost:3000/api/auth", redirected: false, status: 401, ok: false, …} body : (...) bodyUsed : false headers : Headers {} ok : false redirected : false status : 401 statusText : "Unauthorized" type : "cors" url : "http://localhost:3000/api/auth"

Fetch failed loading: POST "http://localhost:3000/api/auth".

Server Side:

app.ts

import express from 'express';
import logger from 'morgan';
import bodyParser from 'body-parser';
import mongoose from 'mongoose';
import passport from 'passport';
import cors from "cors";

import Routes from './routes';
import Config from './config/config';

class App {

    public app: express.Application;
    public config: any;

    constructor() {

        this.app = express();

        this.environment();
        this.database();
        this.middleware();
        this.routes();

    }

    private environment(): void {

        this.config = new Config();

    }

    private database(): void {

        const uri: string = this.config.db.uri;
        const options: any = this.config.db.options;

        mongoose.connect(uri, options).then(

            () => {
                console.log("MongoDB Successfully Connected On: " + this.config.db.uri)
            },
            (err: any) => {
                console.error("MongoDB Error:", err);
                console.log('%s MongoDB connection error. Please make sure MongoDB is running.');
                process.exit();
            }

        );

    }

    private middleware(): void {

        this.app.use(cors());
        this.app.use(logger('dev'));
        this.app.use(express.json());
        this.app.use(express.urlencoded());
        this.app.use(passport.initialize());

    }

    private routes(): void {

        const routes = new Routes(this.app);

    }

}

export default App;

api/auth Route

public store(req, res) {

      console.log(req.body)
}

the req.body is empty.

console

Kay
  • 17,906
  • 63
  • 162
  • 270
  • @Randy No because the request works fine in postman – Kay Jun 20 '18 at 12:58
  • @Randy I have updated my question to show you the code for my server side app. You can see there i have set cors and bodyParser. – Kay Jun 20 '18 at 13:03
  • I have even updated to use express.json and urlencoder instead of bodyparser, but this still does not fix the issue. – Kay Jun 20 '18 at 13:22

1 Answers1

2

You should try adding in the request mode: cors in your request. The body should be a string and you might want to set header with content-type to application/json:

let headers = new Headers();
headers.set('Content-type', 'application/json');

const request = {
    method: 'POST',
    body: JSON.stringify(body),
    mode: 'cors',
    credentials: 'include',
    headers: headers
}

It would also be helpful to see what happens in your browser network tab.

filippo
  • 2,967
  • 1
  • 19
  • 19
  • No authentication token/headed is needed in my request. Is the mode and credentials still required? – Kay Jun 20 '18 at 13:15
  • i have updated my question to include the screenshot of the browser – Kay Jun 20 '18 at 13:18
  • credentials is required if you pass a Cookie in the request or an Authorization header, so I guess it's not required. Sorry I missed there are some other problems in the fetch call. I update the response. – filippo Jun 20 '18 at 13:19
  • sorry i dont understand what you mean. In my body {} you see i am passing in a single product_id input. My request is not using any authorisation headers, it does not need it to call the api. – Kay Jun 20 '18 at 13:21
  • @Kay can you also post a screenshot of the browser network tab with HTTP headers of the request and response. Something like this: https://stackoverflow.com/a/4423097/121199 – filippo Jun 20 '18 at 13:38
  • hey it looks like adding those headers and the json stringify worked. However my response is still the same and not the response from the server. Is there an issue with my await in the index file. – Kay Jun 20 '18 at 13:39
  • the 401 in the response means you are not authorized to access the resource. It might be passport that returns it. What happens if you remove it? – filippo Jun 20 '18 at 13:45
  • Let us [continue this discussion in chat](https://chat.stackoverflow.com/rooms/173478/discussion-between-kay-and-filippo). – Kay Jun 20 '18 at 13:46
  • Just to confirm if i have a token in the headers do i need to set the credentials? – Kay Jun 20 '18 at 16:40
  • Yes if you send a cookie or authorisation token in a cors request you have to set credentials: 'include' – filippo Jun 20 '18 at 16:48
  • when i do that i get the following error.Response to preflight request doesn't pass access control check: The value of the 'Access-Control-Allow-Origin' header in the response must not be the wildcard '*' when the request's credentials mode is 'include'. Origin – Kay Jun 22 '18 at 14:45
  • Yes that's how CORS works. When you send credentials the server must set in the response the http headers 'Access-Control-Allow-Origin' and the value must match the Origin header sent in the request. The '*' in 'Access-Control-Allow-Origin' isn't allowed in this case and the request fails – filippo Jun 22 '18 at 15:19
  • i just made a new questions because i am getting a different error when working with an external api this time. – Kay Jun 22 '18 at 15:33