Проблемы с Cors при попытке использовать jwt для аутентификации на сервере api - PullRequest
0 голосов
/ 08 января 2020

Я создаю API-интерфейс сервера, который будет обрабатывать различные запросы, и интерфейс, чтобы пользователи, вошедшие в систему, могли видеть запросы в календаре. Интерфейс и бэкэнд работают на отдельных nodejs express веб-серверах. Для развертывания реагирующего веб-интерфейса я запустил сборку npm run, а затем скопировал содержимое папки сборки в общую папку c серверов внешнего интерфейса. Это может быть не лучший способ развернуть реактивное веб-приложение, хотя?

В любом случае все хорошо работает на localhost, но как только я пытаюсь развернуть его как два отдельных приложения heroku, у меня возникают проблемы с корсом, и я не могу понять, как это исправить.

Ошибка cors I get is:

Блокирован перекрестный запрос: одна и та же политика происхождения запрещает чтение удаленного ресурса на https://example.com/request/allApproved. (Причина: отсутствует заголовок CORS 'Access-Control-Allow-Origin'.)

структура файла выглядит следующим образом: backend:

src
 |- public
  |- controller
   |- various repositories.js files
  |- models
   |- mongodb model.js files
  |- router
   |- routes for the repositories.
 |- .env
 |- app.js
 |- dbParser.js
 |- passportSetup.js

У меня есть настройки cors в app. js, который выглядит следующим образом:

require("dotenv").config();
const express = require("express");
const MongoDBStore = require("connect-mongo")(session);
const Mongoose = require("./dbParser");
var User = require("./public/models/user");
var cors = require("cors");
var Request = require("./public/models/request");
const passport = require('passport');
require('./passportSetup')(passport);
const jwt = require('jsonwebtoken');
const LocalStrategy = require('passport-local').Strategy;
const passportJWT = require('passport-jwt');
const JWTStrategy = passportJWT.Strategy;

// allow localhost and heroku frontend url.
var allowedOrigins = [process.env.DEVELOPMENT_ORIGIN, process.env.LIVE_FRONT];
app.use(cors({
  origin: function(origin, callback){    
    // allow requests with no origin 
    // (like mobile apps or curl requests)
    if(!origin) return callback(null, true);

    if(allowedOrigins.indexOf(origin) === -1){
      var msg = 'The CORS policy for this site does not ' +
                'allow access from the specified Origin.';
      return callback(new Error(msg), false);
    }    return callback(null, true);
  },
  credentials: true
}));

app.post("/login", (req, res) => {
    User.findOne({ email: req.body.email.toLowerCase() }, function(err, user) {
      if (err || user == null) {
        console.log('wrong username')
        res.status(401).json({
            error: 'wrong credetials'
        });
      } else {
        if (user.validPassword(req.body.password)) {
          //console.log(user.toJSON())
          let token = jwt.sign(user.toJSON(), 'secret', {
            expiresIn: 604800 // 1 week

          });
          res.status(200).json({success: true, jwt: 'jwt ' + token});
        } else {
          res.status(402).json({
            login: 'noo'
          });
        }
      }
    }); 
});

app.post("/authorize", passport.authenticate('jwt', { session: false}), (req, res) => {
  if (req.user.userId != undefined) {
    User.findOne({  }, function(err, user) {
      if (err || user == null) {
        res.sendStatus(400);
      } else if(user){
        let filteredUser = {
          name: req.user.name,
          lastName: req.user.lastName,
          isAdmin: req.user.isAdmin,
          userId: req.user.userId,
          region: req.user.region,
          email: req.user.email
        };
        res.status(200).json(filteredUser);
      } else {
        res.sendStatus(401)
      }
    });
  } else {
    res.sendStatus(401);
  }
});

app.use("/user", passport.authenticate('jwt', {session: false}), userRoutes);
app.use("/request", passport.authenticate('jwt', {session: false}), requestRoutes);

app.all("*", (req, res) => {
  res.sendStatus(404);
});
app.listen(process.env.PORT || 8080);

в интерфейсе реагирования я использую ax ios, чтобы совершать звонки на мой API

const login = (email: string, password: string): any => axios(`${process.env.REACT_APP_API_URL}/login`, {
    method: "POST",
    withCredentials: true,
    data: { email, password }
});

const allApprovedVacReqs = (): any => axiosWrapper(`${process.env.REACT_APP_API_URL}/request/allApproved`, {
    method: "GET",
    withCredentials: true,
    headers: {
        Authorization: localStorage.getItem('jwt'),
    }
});

requestRoutes. js (помещено в папку маршрутов)

var express = require("express");
var router = express.Router();
const requestRepository = require('../controller/requestRepository')

router.route('/allPending').get(requestRepository.getAllPending)
router.route('/allDenied').get(requestRepository.getAllDenied)

router.route('/allApproved').get(requestRepository.getAllApproved)

module.exports = router;

Я знаю, что jwt, вероятно, не следует хранить в локальном хранилище, но он удаляется при выходе из системы, и для моих целей это, вероятно, нормально.

сервер nodejs, на котором я размещаю файлы, которые я получаю npm run build

const express = require('express')
const app = express()
const port =  process.env.PORT || 3000
const path = require('path')
app.use(express.static(path.join(__dirname, 'public')))

app.use(function(req, res, next) {
    res.set('Access-Control-Allow-Credentials', true);
    next();
  });

app.get('*', (req, res) =>{
    res.sendFile(path.join(__dirname+ '/public/index.html'))
})
app.listen(port, () => console.log(`frontend listening on port ${port}!`))

Я могу войти в систему очень хорошо, но когда я пытаюсь получить доступ к маршруту / запросу / всеУтверждено и проходит JWT в шапке я сталкиваюсь с проблемами Cors.

Я очень ценю любые мысли о том, как решить эту проблему.

...