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 'ヘッダーがありません。
私はたくさんの方法を試しましたが、何もしませんでした...何かアイデアはありますか?
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)
を確認できます(私がしないため)データベース内のユーザーを知りません)
私は私のローカルであなたのコードを試しました、おそらくあなたはすべてのエラーをテストして処理していなかったかもしれません、それはあなたのアプリを残念ながらクラッシュさせます。
私はあなたのコードを実行し、おそらくjsonwebtoken
エラーの問題に気づきました:
エラー:secretOrPrivateKeyには値が必要です
_process.env.JWT_KEY || 'Require key here!!!',
_を試して、環境に_JWT_KEY
_を設定するか、サーバーのデフォルトキーとして_||
_を使用してください。
多分それはあなたの問題を修正します。
私はあなたのコードにいくつかの推奨事項を持っています:
User.findOne()
の代わりにUser.find()
を使用してくださいapp.use(cors());
を使用してくださいjsonwebtoken
は、サーバーで実行する場合、同期ではなくAsynchronousを使用する必要があります。これは私のソースコードです
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
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))
}
}
私は同じ問題を扱っていますが、あなたの問題はCORSではないと思います。サーバーログをテストできますか。私の場合、パッケージに問題があり、503も 'Access-Control-Allow-Origin'ヘッダー、CORSエラーが発生していました。パッケージとjwtの問題を修正すると、CORSの問題が解決します!.