Я создаю 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.
Я очень ценю любые мысли о том, как решить эту проблему.