Проблемы с CORS на HEROKU - PullRequest
       7

Проблемы с CORS на HEROKU

0 голосов
/ 20 декабря 2018

У меня проблема с CORS на Heroku.

Это мой код на сервере

import express from 'express';
import bodyParser from 'body-parser';
import mongoose from 'mongoose';
require('dotenv').config()

import filmRoutes from './api/routes/films'
import userRoutes from './api/routes/users'

const app = express()

const DBNAME = process.env.DB_USER 
const DBPASSWORD = process.env.DB_PASS


mongoose.connect(`mongodb://${DBNAME}:${DBPASSWORD}@ds157422.mlab.com:57422/filmbase`, {useNewUrlParser: true})

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

app.use(bodyParser.urlencoded({extended: false}));
app.use(bodyParser.json());

app.use('/films', filmRoutes)
app.use('/users', userRoutes)


export default app;

Это мой почтовый запрос

  CheckLogin = () => {
    const data = {
      name: this.state.formInput.login.value,
      password: this.state.formInput.password.value
    }
    axios.post('https://whispering-shore-72195.herokuapp.com/users/login', data)
    .then(response=>{
      console.log(response);
      const expirationDate = new Date(new Date().getTime() + response.data.expiresIn * 1000)
      localStorage.setItem('token', response.data.token)
      localStorage.setItem('expirationDate', expirationDate)
      this.context.loginHandler()
    })
    .catch(err=>{
      console.log(err)
    })

    console.log(data);
  }

Это ОШИБКА

Доступ к XMLHttpRequest по адресу * https://whispering -shore-72195.herokuapp.com / users / login 'from origin' https://mighty -citadel-71298.herokuapp.com 'заблокировано политикой CORS: в запрошенном ресурсе отсутствует заголовок «Access-Control-Allow-Origin».

Я перепробовал много методов и ничего ... Есть идеи?

Ответы [ 3 ]

0 голосов
/ 21 декабря 2018

Это мой исходный код

Сервер

userController.js

import mongoose from 'mongoose';
import User from '../models/user';
import bcrypt from 'bcrypt';
import jsw from 'jsonwebtoken'

export default {

  async send(req, res ,next){
    User.find({name: req.body.name})
    .exec()
    .then(user=>{
      if(user.length >= 1){
        return res.status(409).json({
          message: 'User exist'
        });
      }
      else{
        bcrypt.hash(req.body.password, 10, (err,hash)=>{
          if(err){
            return res.status(500).json({
              error: err
            });
          }else{
            const user = new User({
              _id: new mongoose.Types.ObjectId(),
              name: req.body.name,
              password: hash
            });
            user
            .save()
            .then(result=>{
              console.log(result);
              res.status(201).json({
                message: 'user created'
              });
            })
            .catch(err=>{
              console.log(err)
              res.status(500).json({
                error: err
              })
            })
          }
        })
      }
    })
  },

  async login(req, res, next){
    User.find({name: req.body.name})
    .exec()
    .then(user=>{
      if(user.length < 1){
        return res.status(404).json({
          message: 'user exist'
        })
      }
      bcrypt.compare(req.body.password, user[0].password, (err, result)=>{
        if(err){
          return res.status(404).json({
            message: 'bcrypt failed'
          })
        }
        if(result){
          const time = '1'
          const token = jsw.sign({
            name: user[0].name,
            iserId: user[0]._id
          },process.env.JWT_KEY,
          {
            expiresIn: `${time}h`
          }
          );
          return res.status(200).json({
            message: 'auth success',
            token: token,
            expiresIn: time
          })
        }
        return res.status(404).json({
          message: 'Auth failed'
        })
      })
    })
    .catch(err=>{
      res.status(500).json({
        error: err
      })
    })
  }

}

app.js

import express from 'express';
import bodyParser from 'body-parser';
import mongoose from 'mongoose';
require('dotenv').config()

import filmRoutes from './api/routes/films'
import userRoutes from './api/routes/users'

const app = express()

const DBNAME = process.env.DB_USER 
const DBPASSWORD = process.env.DB_PASS


mongoose.connect(`mongodb://${DBNAME}:${DBPASSWORD}@ds157422.mlab.com:57422/filmbase`, {useNewUrlParser: true})

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

app.use(bodyParser.urlencoded({extended: false}));
app.use(bodyParser.json());

app.use('/films', filmRoutes)
app.use('/users', userRoutes)


export default app;

Клиент

LoginPades.js

import React from 'react';
import './LoginPages.css';
import axios from 'axios'

import AuthContext from '../../../auth-context';
import Input from '../../Input/Input';

class Login extends React.Component {
  static contextType = AuthContext;
  state={
    formInput:{
      login:{
        elementType: 'input',
        elementConfig: {
          type: 'text',
          placeholder: 'Login'
        },
        Value:''
      },
      password:{
        elementType: 'input',
        elementConfig:{
          type: 'text',
          placeholder: 'Password'
        },
        Value:'',
      }
    }
  }

  inputChangeHandler = (event, id) => {
    let value = event.target.value;
    const updateState = {
      ...this.state.formInput
    }
    const updateElement = {
      ...updateState[id]
    }
    updateElement.value = value;
    updateState[id] = updateElement

    this.setState({
      formInput: updateState
    })
  }

  CheckLogin = () => {
    const data = {
      name: this.state.formInput.login.value,
      password: this.state.formInput.password.value
    }
    axios.post('https://whispering-shore-72195.herokuapp.com/users/login', data)
    .then(response=>{
      console.log(response);
      const expirationDate = new Date(new Date().getTime() + response.data.expiresIn * 1000)
      localStorage.setItem('token', response.data.token)
      localStorage.setItem('expirationDate', expirationDate)
      this.context.loginHandler()
    })
    .catch(err=>{
      console.log(err)
    })

    console.log(data);
  }

  render(){
    const inputsArray = [];
    for (let key in this.state.formInput){
      inputsArray.push({
        id: key,
        config: this.state.formInput[key]
      })
    }

    let inputs =(
      <>
      {inputsArray.map(inputElement=>(
        <Input
        className='input-lodig-password'
        key={inputElement.id} 
        elementType={inputElement.config.elementType}
        elementConfig={inputElement.config.elementConfig}
        value={inputElement.value}
        changed={(event)=>this.inputChangeHandler(event, inputElement.id)}
        />
      ))}
      </>
    ) 


    return(
      <div className='login'>
        <div className='card'>
          <div className='spider'>
            {/* <img src='http://www.officialpsds.com/images/thumbs/Spiderman-Logo-psd59240.png' alt='pajak'/> */}
          </div>
          <p className='opis'>Zaloguj sie do groty rozpusty</p>
          <form className='login-inputy'>
             {inputs}
          </form>
            <button className='btn-login' onClick={this.CheckLogin}>Zaloguj sie</button>
        </div>
      </div>
    )
  }
}

export default Login
0 голосов
/ 22 декабря 2018

router / user.js

import express from 'express';
import userController from '../controllers/usersController';
import {catchAsync} from '../moddlewares/errors';


const router = express.Router();

router.post('/signup',catchAsync(userController.send))
router.post('/login', catchAsync(userController.login))

export default router

model / user.js

import mongoose from 'mongoose'

const userSchema = mongoose.Schema({
  _id: mongoose.Schema.Types.ObjectId,
  name: {type: String, required: true},
  password: {type: String, required: true}
})

const user = mongoose.model('User', userSchema);

export default user

catchAsync.js

export function catchAsync(cb){
  return (req,res,next)=>{
    cb(req,res,next).catch(err=>next(err))
  }
}
0 голосов
/ 21 декабря 2018

У вас есть домен перекрестного происхождения на https://whispering -shore-72195.herokuapp.com от источника https://mighty -citadel-71298.herokuapp.com

Вы можете попробовать пакет npm cors в качестве промежуточного программного обеспечения вместо своего специального промежуточного программного обеспечения.Пакет CORS позволяет выполнять множественную настройку и очень прост в использовании.

Простое использование (включить все запросы CORS)

import express from 'express';
import bodyParser from 'body-parser';
import mongoose from 'mongoose';
import cors from 'cors';
require('dotenv').config()

import filmRoutes from './api/routes/films'
import userRoutes from './api/routes/users'

const app = express()

const DBNAME = process.env.DB_USER 
const DBPASSWORD = process.env.DB_PASS


mongoose.connect(`mongodb://${DBNAME}:${DBPASSWORD}@ds157422.mlab.com:57422/filmbase`, {useNewUrlParser: true})

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

app.use(cors()); // <---- use cors middleware

app.use(bodyParser.urlencoded({extended: false}));
app.use(bodyParser.json());

app.use('/films', filmRoutes)
app.use('/users', userRoutes)


export default app;

Редактировать:

Я протестировал ваш клиентский логин на ваш сервер с https, и он работает без проблем с CORS.Возможно, вы исправили это успешно.

Я пробовал с простым на StackBlitz , и он успешно работает.

Вы можете попробовать войти https://js -53876623.stackblitz.io / и просматривать вкладку сети при проверке и видеть OPTIONS (200 status) и POST (404 not found) (потому что я не знаю ни одного пользователя в вашей базе данных)

Редактировать 22 декабря 2018 - 7:18PM

Я попробовал ваш код на своем локальном компьютере, возможно, вы не проверяли и обрабатывали все ошибки, к сожалению, это приводит к сбою приложения.

Я запустил ваш код и заметил, чтопроблема может быть jsonwebtoken ошибка:

Ошибка: secretOrPrivateKey должен иметь значение

Пожалуйста, попробуйте с process.env.JWT_KEY || 'Require key here!!!', и установите JWT_KEY в вашей среде или использовании|| как ключ по умолчанию на сервере.

Возможно, это решит вашу проблему.

Рекомендует:

У меня есть несколько рекомендаций для вашего кода:

  • Пожалуйста, используйте User.findOne() вместо User.find()
  • Пожалуйста, используйте app.use(cors());
  • jsonwebtoken следует использовать Асинхронный вместо синхронизации при запуске на сервере.
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...