PUT метод не разрешен с http-прокси - PullRequest
0 голосов
/ 10 апреля 2020

При вызове моего метода PUT я получил эту ошибку:

<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML 2.0//EN">
<html>
    <head>
        <title>403 Forbidden</title>
    </head>
    <body>
        <h1>Forbidden</h1>
        <p>You don't have permission to access this resource.</p>
    </body>
</html>

У меня есть некоторая аутентификация jwt, поэтому я поставил здесь полный код: он работает с методами GET и POST

const express = require('express');
const logger = require('morgan');
var fs = require('fs');
var https = require('https');
var privateKey  = fs.readFileSync('/etc/letsencrypt/live/hidden/privkey.pem', 'utf8');
var certificate = fs.readFileSync('/etc/letsencrypt/live/hidden/fullchain.pem', 'utf8');
const util = require('util')
var credentials = {key: privateKey, cert: certificate};
var queryString = require('querystring');

const bodyParser = require('body-parser');
const app = express();
const jwt = require('jsonwebtoken');
// import passport and passport-jwt modules
const passport = require('passport');
const passportJWT = require('passport-jwt');

const bcrypt = require('bcryptjs');
const Sequelize = require('sequelize');

var httpProxy = require('http-proxy');
var apiProxy = httpProxy.createProxyServer();
var backend = 'http://localhost:8484';

// initialize an instance of Sequelize
const sequelize = new Sequelize({
//hiden///
});


// ExtractJwt to help extract the token
let ExtractJwt = passportJWT.ExtractJwt;

// JwtStrategy which is the strategy for the authentication
let JwtStrategy = passportJWT.Strategy;
let jwtOptions = {};
jwtOptions.jwtFromRequest = ExtractJwt.fromAuthHeaderAsBearerToken();
jwtOptions.secretOrKey = 'hidden';

// lets create our strategy for web token
let strategy = new JwtStrategy(jwtOptions, function(jwt_payload, next) {
  console.log('payload received', jwt_payload);
  let user = getUser({ id: jwt_payload.id });
  if (user) {
    next(null, user);
  } else {
    next(null, false);
  }
});
// use the strategy
passport.use(strategy);


app.use(passport.initialize());
app.use(logger(':date[iso] :method :url :status :response-time ms - :res[content-length]'));

// parse application/json
app.use(bodyParser.json());

//parse application/x-www-form-urlencoded
app.use(bodyParser.urlencoded({ extended: true }));

// check the databse connection

sequelize
  .authenticate()
  .then(() => console.log('Connection has been established successfully.'))
  .catch(err => console.error('Unable to connect to the database:', err));


// create user model
const User = sequelize.define('user', {
  name: {
    type: Sequelize.STRING,
    allowNull: false
  },
  code_event: {
    type: Sequelize.INTEGER,
    allowNull: false
  },
  password: {
    type: Sequelize.STRING,
    allowNull: false
  },
});


// create table with user model
User.sync()
  .then(() => console.log('User table created successfully'))
  .catch(err => console.log('did you enter wrong database credentials?'));

// create some helper functions to work on the database
const createUser = async ({ name, password, code_event }) => { 
    try{
        return await User.create({ name, password, code_event });
    }
    catch (error) { 
        // your catch block code goes here
    }
};

const getAllUsers = async () => {
    try{
        return await User.findAll();
    }
    catch (error) { 
        // your catch block code goes here
    }
};

const getUser = async obj => {
    try{
        return await User.findOne({where: obj,});
    }
    catch (error) { 
        // your catch block code goes here
    }
};


// get all users
app.get('/users', function(req, res) {
  getAllUsers().then(user => res.json(user)); 
});

// register route
app.post('/register', function(req, res, next) {
    console.log(req.body);
  let { name, password, code_event } = req.body;
  bcrypt.genSalt(10, (err, salt) => {
                    if(err) throw err;
                    bcrypt.hash(password, salt,
                                        (err, hash) => {
                        if(err) throw err;
                        password = hash;
                        createUser({ name, password, code_event }).then(user =>
                            res.json({ user, msg: 'account created successfully' })
                        )
                           .catch(err => res.status(400).json(err));
                   });
                });

});


// login route

app.post('/login', async function(req, res, next) { 
        console.log(req.body);

  const { name, password , code_event} = req.body;
  if (name && password) {
    // we get the user with the name and save the resolved promise returned
    let user = await getUser({ name, code_event});
    if (!user) {
      res.status(401).json({ msg: 'No such user found', user });
    }
    bcrypt.compare(password, user.password)
        .then(isMatch => {
            if (isMatch) {
                const payload = {id: user._id};
                // let token = jwt.sign(payload, jwtOptions.secretOrKey, { expiresIn: 36000 }, (err, token) => {
                //     if (err) res.status(500).json({ error: "Error signing token", raw: err }); 
                //     res.json({ msg: 'ok', token: token });
                // });
                let token = jwt.sign(payload, jwtOptions.secretOrKey);
                res.json({ msg: 'ok', token: token });
            } else {
                res.status(401).json("Password is incorrect");
        }
    });

  }
});

apiProxy.on( 'proxyReq', ( proxyReq, req, res, options ) => {
console.log("body " +util.inspect(req.body, false, null, true /* enable colors */));
        if ( !req.body || !Object.keys( req.body ).length ) {
            return;
        }

        let contentType = proxyReq.getHeader( 'Content-Type' );
        let bodyData;

        if ( contentType.includes( 'application/json' ) ) {
            bodyData = JSON.stringify( req.body );
        }

        if ( contentType.includes( 'application/x-www-form-urlencoded' ) ) {
            bodyData = queryString.stringify( req.body );
        }

        if ( bodyData ) {
            proxyReq.setHeader( 'Content-Length', Buffer.byteLength( bodyData ) );
            proxyReq.write( bodyData );
        }
});


app.all("/*",  passport.authenticate('jwt', { session: false }), function(req, res) {
  console.log("req all" + req);
    apiProxy.web(req, res, {target: backend});
});

app.on('upgrade', function (req, socket, head) {
   console.log("req on" + req);
  apiProxy.ws(req, socket, head, {target: backend});
});

var httpsServer = https.createServer(credentials, app);

// start the app
httpsServer.listen(8383, function() {
  console.log("Express is running on port 3000");
});

Это работает с моими методами POST. Я не знаю, куда это идет, потому что при вызове метода у меня должна быть трассировка в моих лог-файлах. Я вижу сообщения POST от GET, но не PUT.

Есть идеи?

...