Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Using axios to get data from "/get" to "/", but geting 403 error. (Express, mysql, JWT) #211

Open
JohnReyes-Dev opened this issue Sep 25, 2020 · 3 comments

Comments

@JohnReyes-Dev
Copy link

I'm not sure if this is the right place to ask this question, but...

What I'm trying to do is get json data from "/get" to "/", but I'm not sure why axios keeps giving my a 403 error. From what I read, axios isn't the issue, but cors is. I tried all the ways that people are recommending, but nothing is working. What I'm I doing wrong within my code? I'm also seeing "Referrer Policy: strict-origin-when-cross-origin" in the Header, but I'm not sure if that's what's causing this issue.

const express = require("express");
const mysql = require("mysql2");
var app = express();
const bodyparser = require("body-parser");
const cors = require("cors");
const cookieParser = require("cookie-parser");
const expressSession = require("express-session")({
secret: "secret",
resave: false,
 saveUninitialized: false,
});
const passport = require("passport");

const jwt = require('jsonwebtoken');

app.use(passport.initialize());
app.use(passport.session());

app.use(bodyparser.json());
app.use(cors());

 app.use(bodyparser.urlencoded({ extended: false }));
 app.use(express.json());
 app.use(cookieParser());
 app.use(expressSession);

 const axios = require('axios');

 var mysqlConnection = mysql.createConnection({
  host: "localhost",
  user: "root",
  password: "",
  database: "sys",
  multipleStatements: true,
});

 mysqlConnection.connect((err) => {
   if (!err) console.log("DB connection succeded.");
   else
     console.log(
       "DB connection failed \n Error : " + JSON.stringify(err, undefined, 2)
    );
});

 app.use(function(req, res, next) {
  res.header("Access-Control-Allow-Origin", "*");
  res.header('Access-Control-Allow-Methods', 'DELETE, PUT, GET, POST');
  res.header("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept");
 next();
});

app.listen(5000, () =>
  console.log("Express server is runnig at port no : 5000")
);

 app.get("/get", authenticateToken, (req, res) => {

  jwt.verify(req.token, 'secretpassword', (err) => {
    if (err) {
      res.sendStatus(403);
    } else {
      mysqlConnection.query("SELECT * FROM sys.jobs", (err, rows) => {
        if (rows === undefined) {
          res.send("Hello World!");
        } else {
          res.send(rows);
        }
      });
     }

  });
});

 app.get("/", authenticateToken, (req, res) => {

  jwt.verify(req.token, 'secretpassword', async (err) => {
    if (err) {
      res.sendStatus(403);
    } else {

    let response = await axios.get('http://localhost:5000/' +'get', {
      withCredentials: true,
      headers: {
        'Access-Control-Allow-Origin': '*',
        'Authorization': `Bearer 
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpZCI6MSwiaWF0IjoxNjAwOTIyMTQ0LCJleHAiOjE2MDg2OTgxNDR9.aRsw- 
jEQJ-7mlO10nBKA5VT3IL7P0b9T9K0C8aT8sUs`
  
   }
    });

       res.send(response.data);

    }
  });
});

app.post("/login", async (req, res) => {
  try {
    const { email } = req.body;

    mysqlConnection.query("SELECT * FROM sys.users WHERE email = ?", [email], async (error, results) => {

      const id = results[0].id;
      const token = jwt.sign({ id }, "secretpassword", {
      expiresIn: '90d'
    });

  const cookieOptions = {
    expires: new Date(
      Date.now() + 90 * 24 * 60 * 60 * 1000
    ),
    secure: false,
    httpOnly: true
  }

  res.cookie('jwt', token, cookieOptions);

  res.status(200).redirect("/get");
  });
  }
  catch (error) {
  console.log(error);
 }
}
);


function authenticateToken(req, res, next) {

  const bearerHeader = req.cookies.jwt;

  if (typeof bearerHeader !== 'undefined') {

  req.token = bearerHeader;

  next();
} else {

   res.sendStatus(403);
 }
}
@douglasnaphas
Copy link

@RukaiJohn Can you provide a list of specific steps to follow in order to reproduce the errors that you are seeing?

This should include anything I have to run against my local mysql server to set up a user, and, especially, the actions taken within the browser, and any JavaScript that runs client-side.

@JohnReyes-Dev
Copy link
Author

How i created the mysql table.

CREATE TABLE jobs.user (
id INT NOT NULL AUTO_INCREMENT,
email VARCHAR(45) NOT NULL,
PRIMARY KEY (id));

Step #1:
Front end I'm using Vue for the login. So 'http//localhost:8080/login' so I can authenticate/create a token for the user. The action is taken place in http://localhost:5000/login. After that http://localhost:5000/get can be accessed and it can show the json data from the database.

<template>
<form style="width: 75%; max-width: 700px; margin-left: auto; margin-right: auto;"
    action="http://localhost:5000/login" method="POST">
    <p class="h4 text-center mb-4">Sign in</p>
    <label for="defaultFormLoginEmailEx" class="grey-text">Your email</label>
    <input type="email" id="defaultFormLoginEmailEx" class="form-control" name="email"/>
    <br />
    <label for="defaultFormLoginPasswordEx" class="grey-text">Your password</label>
    <input type="password" id="defaultFormLoginPasswordEx" class="form-control" name="password"/>
    <div class="text-center mt-4">
        <button class="btn btn-indigo" type="submit">Login</button>
    </div>
</form>
</template>

 <script>
   export default {
       data() {
           return {}
       }
   }
  </script>

Step #2

Since I wasn't successful using axios in the front end. I decided to do it in the backend like this. But it gave my the same 403 error when I tried to get the data from http://localhost:5000/get

app.get("/", authenticateToken, (req, res) => {

 jwt.verify(req.token, 'secretpassword', async (err) => {
    if (err) {
      res.sendStatus(403);
    } else {

    let response = await axios.get('http://localhost:5000/' +'get', {
      withCredentials: true,
      headers: {
      'Access-Control-Allow-Origin': '*',
      'Authorization': `Bearer 
            eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpZCI6MSwiaWF0IjoxNjAwOTIyMTQ0LCJleHAiOjE2MDg2OTgxNDR9.aRsw- 
            jEQJ-7mlO10nBKA5VT3IL7P0b9T9K0C8aT8sUs`

     }
     });

        res.send(response.data);

    }
  });
});

*****If I'm not making much sense, I can give you access to my project in github and you can take a look at it if you have time.

@douglasnaphas
Copy link

I would want to try to figure out the issue using the code you have provided. If I address it using access to your repo, then someone else finding this Issue in the future would not be able to follow along.

Unfortunately, I probably won't be able to look in more detail for at least a few more days, but here are some thoughts that might assist with debugging:

  1. Instead of running one server on http://localhost:8080 (your front-end), and another on http://localhost:5000 (your back-end), try temporarily having http://localhost:5000/front-end return the HTML of your front-end. That way, you can get your login flow working in a same-site context, so that there will be guaranteed to be no CORS issues. Once that's working, you can run the working front-end code from http://localhost:8080, and any issues that come up will probably be CORS issues, but you won't have to debug CORS issues at the same time as general app issues. Depending on your needs, you could even just leave it with the back-end and front-end on the same domain, and never have to worry about CORS.
  2. You are running axios.get with Access-Control-Allow-Origin: * as a request header. Access-Control-Allow-Origin is a response header.
  3. The fact that you're getting 403 means that this is probably an issue outside of CORS. I'm pretty sure that this library never sends a 403 response, and your application code has a few different places where it sends 403.
  4. CORS is between the browser and the server. It's a way for a server to tell a browser the circumstances under which the browser should make exceptions to its same-origin policy. It doesn't make sense to have your back-end make a request to your back-end, like you do to http://localhost:5000/get while servicing requests to http://localhost:5000/, to handle a CORS issue.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

3 participants