У меня есть простое приложение, которое регистрирует и регистрирует пользователей в базе данных SQLite, которое прекрасно работает на localhost
, но не может заставить его работать при развертывании. Возвращает ошибку 405 (Not Allowed)
с Error: Request failed with status code 405
. Мой сервер - Ubuntu, на котором работает Nginx.
Мои действия (с использованием Vuex) для обработки имени входа / регистрации behviours:
actions: {
// Login user action.
login({ commit }, user) {
// Use Promise object to return desired objects.
return new Promise((resolve, reject) => {
commit("auth_request"); // Vuex helper to trigger mutations.
// Make a call to the server's login and return necessary data.
axios({
url: "http://localhost:3000/login", // Uncomment for localhost.
// url: "http://XX.XX.XX.XX/login", // Uncomment for deployment.
data: user,
method: "POST"
})
// Fetch necessary data from response.
.then(resp => {
// Necessary data.
const token = resp.data.token;
const user = resp.data.user;
localStorage.setItem("token", token); // Store token on localStorage.
axios.defaults.headers.common["Authorization"] = token; // Set Axio's header.
commit("auth_success", token, user); // Vuex helper to trigger mutations, which passes JWT token and user data.
resolve(resp); // Return Promise object that is resolved with a given value.
})
// Catch errors.
.catch(err => {
commit("auth_error"); // Vuex helper to trigger mutations.
localStorage.removeItem("token"); // Remove JWT token from the localStorage.
reject(err); // Return Promise object that is rejected with a given reason.
});
});
},
// Register user action.
register({ commit }, user) {
// Use Promise to return desired objects.
return new Promise((resolve, reject) => {
commit("auth_request"); // Vuex helper to trigger mutations.
// Make a call to the server's register and return necessary data.
axios({
url: "http://localhost:3000/register", // Uncomment for localhost.
// url: "http://XX.XX.XX.XX/register", // Uncomment for deployment.
data: user,
method: "POST"
})
// Fetch necessary data from response.
.then(resp => {
// Necessary data.
const token = resp.data.token;
const user = resp.data.user;
localStorage.setItem("token", token); // Store token on localStorage.
axios.defaults.headers.common["Authorization"] = token; // Set Axio's header.
commit("auth_success", token, user); // Vuex helper to trigger mutations, which passes JWT token and user data.
resolve(resp); // Return Promise that is resolved with a given value.
})
// Catch errors.
.catch(err => {
commit("auth_error", err); // Vuex helper to trigger mutations.
localStorage.removeItem("token"); // Remove JWT token from the localStorage.
reject(err); // Return Promise object that is rejected with a given reason.
});
});
},
Для сервера я включаю все необходимыеЗаголовки HTTP с регистрацией маршрутов таким образом:
#!/usr/bin/env node
"use strict";
const express = require("express");
const DB = require("./db");
const config = require("./config");
const bcrypt = require("bcrypt");
const jwt = require("jsonwebtoken");
const bodyParser = require("body-parser");
// Create required database, Express server and routing.
const db = new DB("sqlitedb");
const app = express();
const router = express.Router();
router.use(bodyParser.urlencoded({ extended: false }));
router.use(bodyParser.json());
// CORS middleware configuration to avoid cross origin resource errors.
const allowCrossDomain = function(req, res, next) {
res.header("Access-Control-Allow-Origin", "*");
res.header("Access-Control-Allow-Methods", "*");
res.header("Access-Control-Allow-Headers", "*");
next();
};
app.use(allowCrossDomain);
// Route for new users registration.
router.post("/register", function(req, res) {
// Pass request body to database method and callback function to handle the response.
db.insert([req.body.email, bcrypt.hashSync(req.body.password, 8)], function(
err
) {
if (err)
return res.status(500).send("There was a problem registering the user.");
db.selectByEmail(req.body.email, (err, user) => {
if (err) return res.status(500).send("There was a problem getting user");
// User successfully registered, create an authentication token (JWT).
let token = jwt.sign({ id: user.id }, config.secret, {
expiresIn: 86400 // 24 hours expiration time.
});
res.status(200).send({ auth: true, token: token, user: user }); // Send 200 HTTP "OK" response, user successfully registered.
});
});
});
// Route for users login.
router.post("/login", (req, res) => {
db.selectByEmail(req.body.email, (err, user) => {
if (err) return res.status(500).send("Error on the server."); // Some kind of server error.
if (!user) return res.status(404).send("No user found."); // User not found.
// Check if given password mathces password in a database.
let passwordIsValid = bcrypt.compareSync(req.body.password, user.user_pass);
if (!passwordIsValid)
return res.status(401).send({ auth: false, token: null }); // Password doesn't match, don't sign in user.
// Password matches, sign in user.
let token = jwt.sign({ id: user.id }, config.secret, {
expiresIn: 86400 // 24 hours expiration time.
});
res.status(200).send({ auth: true, token: token, user: user }); // Send 200 (OK) HTTP response, user successfully logged in.
});
});
app.use(router); // Make the application accessible.
let port = process.env.PORT || 3000; // Dynamically generated port by hosting system or on localhost it's 3000.
app.listen(port, function() {
console.log("Express server listening on port " + port);
});
Мой nginx.conf
файл для обработки этого приложения выглядит следующим образом (это HTTP, а не HTTPS):
server {
listen 80;
listen [::]:80;
root /var/www/html;
index index.html;
server_name XX.XX.XX.XX;
location / {
try_files $uri $uri/ /index.html;
add_header Access-Control-Allow-Origin *;
add_header Access-Control-Allow-Methods *;
add_header Access-Control-Allow-Headers *;
}
}
С илибез этих заголовков (в nginx.conf
) это не меняет поведение. Я предполагаю, что это какая-то неправильная конфигурация на стороне сервера, потому что, как сказано на localhost
, все работает отлично. Есть ли что-то, что мне не хватает? Для развертывания я раскомментирую url: "http://XX.XX.XX.XX/...
и комментирую логику url: "http://localhost:8080/...
.
Edit1:
Добавление хака error_page 405 = 200 $uri;
к nginx.conf
устраняет эту ошибку, но затемвозвращает мне undefined
.