web-dev-qa-db-ja.com

HEROKUでのCORSの問題

HerokuのCORSに問題があります。

これはサーバー上の私のコードです

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);
  }

これはエラーです

Originから ' https://whispering-shore-72195.herokuapp.com/users/login 'にあるXMLHttpRequestへのアクセス ' https://mighty-citadel-71298.herokuapp.com 'はCORSポリシーによってブロックされています:要求されたリソースに' Access-Control-Allow-Origin 'ヘッダーがありません。

私はたくさんの方法を試しましたが、何もしませんでした...何かアイデアはありますか?

3
misu jakis

https://whispering-shore-72195.herokuapp.com でOriginドメインを越えました https://mighty-citadel-71298.herokuapp.com

カスタムミドルウェアの代わりにミドルウェアとして npm cors package を試すことができます。 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)を確認できます(私がしないため)データベース内のユーザーを知りません)

2018年12月22日午後7:18を編集

私は私のローカルであなたのコードを試しました、おそらくあなたはすべてのエラーをテストして処理していなかったかもしれません、それはあなたのアプリを残念ながらクラッシュさせます。

私はあなたのコードを実行し、おそらくjsonwebtokenエラーの問題に気づきました:

エラー:secretOrPrivateKeyには値が必要です

_process.env.JWT_KEY || 'Require key here!!!',_を試して、環境に_JWT_KEY_を設定するか、サーバーのデフォルトキーとして_||_を使用してください。

多分それはあなたの問題を修正します。

推奨:

私はあなたのコードにいくつかの推奨事項を持っています:

  • User.findOne()の代わりにUser.find()を使用してください
  • app.use(cors());を使用してください
  • jsonwebtokenは、サーバーで実行する場合、同期ではなくAsynchronousを使用する必要があります。
1
huynhsamha

これは私のソースコードです

サーバ

serController.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
misu jakis

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
misu jakis

私は同じ問題を扱っていますが、あなたの問題はCORSではないと思います。サーバーログをテストできますか。私の場合、パッケージに問題があり、503も 'Access-Control-Allow-Origin'ヘッダー、CORSエラーが発生していました。パッケージとjwtの問題を修正すると、CORSの問題が解決します!.

0
het