При регистрации пользователь создается в базе данных, но токен JWT «не определен» при проверке в браузере - PullRequest
0 голосов
/ 28 января 2020

Я пытаюсь зарегистрировать пользователя, а затем после регистрации в браузере появляется токен, который сохраняется. В настоящее время пользователь зарегистрирован и добавлен в базу данных, но когда я проверяю, в сеансе нет токена (токен: «undefined» в состоянии и реквизитах), и страница не перенаправляется со страницы регистрации.

В консоли моя ошибка:

POST http://localhost:5000/register 404 (Not Found)

Error: Request failed with status code 404 
at createError (createError.js:16) 
at settle (settle.js:17) 
at XMLHttpRequest.handleLoad (xhr.js:61)

Реакция

Приложение. js

import React from "react";
import "./style.scss";
import { BrowserRouter, Route, Switch } from "react-router-dom";
import HomePage from "./home_page.js";
import TitlePage from "./title_page.js";
import AboutPage from "./about_page.js";
import BarberPage from "./barbers_page.js";
import ContactPage from "./contact_page.js";
import GalleryPage from "./gallery_page.js";
import LocationPage from "./location_page.js";
import SeminarsTrainingPage from "./seminars_training_page.js";
import ServicesPage from "./services_page.js";
import AppointmentsPage from "./appointments_page.js";
import RegisterPage from "./views/pages/RegisterPage";
import { connect } from "react-redux";

class App extends React.Component {

  state = {
    token: sessionStorage.getItem("token")
  };

  onRegister = token => {
    sessionStorage.setItem("token", token);
    this.setState({ token });
  };

  render() {
    return (
      <>
        <BrowserRouter>
          <div>
            <Route exact path="/home" component={HomePage} />
            <Route exact path="/about" component={AboutPage} />
            <Route exact path="/barbers" component={BarberPage} />
            <Route exact path="/contact" component={ContactPage} />
            <Route exact path="/gallery" component={GalleryPage} />
            <Route exact path="/location" component={LocationPage} />
            <Route exact path="/seminars-training" component={SeminarsTrainingPage} />
            <Route exact path="/services" component={ServicesPage} />
            <Route exact path="/appointments" component={AppointmentsPage} />
            <Route exact path="/titlepage" component={TitlePage} />
            <Route
              exact
              path="/register"
              render={props => {
                return <RegisterPage {...props} onRegister={this.onRegister} />;
              }}
            />
          </div>
        </BrowserRouter>
      </>
    );
  }
}

const mapStateToProps = state => {
  return {
    token: state.auth.token
  };
};

export default connect(mapStateToProps)(App);

Страница регистрации. js

import React, { Component } from "react";
import RegisterForm from "../../components/Forms/fields/RegistrationForm";

class RegisterPage extends Component {
    render() {
        console.log(this.props);

        return(
            <div>
                <h1>Register a new user</h1>
                <RegisterForm onRegister={this.props.onRegister} />
            </div>
        );
    }
}

export default RegisterPage;

Форма регистрации. js

import React, { Component } from "react";
import axios from "axios";
import { withRouter } from "react-router-dom";
import { setAuthToken } from "../../../actions";
import { connect } from "react-redux"

class RegisterForm extends Component {
  state = {
    email: "",
    password: ""
  };

  onFormSubmit = event => {
    event.preventDefault();
    const { email, password } = this.state;

    axios
        .post('http://localhost:5000/register', { email, password })
        // .then(res => console.log(res))
        // .catch(err => console.log(err))
        .then(res => { this.props.onRegister(res.data.token); this.props.history.push('/') })
        .catch(err => console.error(err))
  };

  onInputChange = (name, event) => {
    this.setState({ [name]: event.target.value });
  };

  render() {
    // console.log(this.props);
    const { email, password } = this.state;

    return (
      <form onSubmit={this.onFormSubmit}>
        <p>
          <label htmlFor="email">Email</label>
          <input
            type="email"
            value={email}
            onChange={event => this.onInputChange("email", event)}
          />
        </p>
        <p>
          <label htmlFor="email">Password</label>
          <input
            type="password"
            value={password}
            onChange={event => this.onInputChange("password", event)}
          />
        </p>
        <p>
          <input type="submit" value="Register New User" />
        </p>
      </form>
    );
  }
}

export default connect(null, {
  setAuthToken
})(withRouter(RegisterForm));

Express

index. js

const express = require("express");
const router = express.Router();
const passport = require("passport")
const AuthRoutes = require("./auth_routes");
const PageController = require('../controller/page_controller')
const AuthController = require('../controller/auth_controller')
const { authRedirect, authorise } = require('../middleware/auth_middleware')

router.use("/auth", AuthRoutes);

router.get('/dashboard', passport.authenticate('jwt', {session: false}), PageController.dashboard)

router.get("/", PageController.index);

router.post('/login', passport.authenticate('jwt', {
    successRedirect: "/dashboard",
    failureRedirect: "/login",
    session: false,
}), AuthController.loginCreate)

module.exports = router;

auth_routes. js

const express = require("express");
const router = express.Router();
const { celebrate, Joi } = require("celebrate");
const AuthController = require("../controller/auth_controller");

router.post("/register", celebrate({
    body: {
        email: Joi.string().email().required(),
        password: Joi.string().required()
    }
}), AuthController.register);

module.exports = router;

auth_controller. js

const { UserModel } = require('../database/models/User')
const JWTService = require("../services/jwt_service");

function register(req, res, next) {
    const { email, password } = req.body;
    const user = new UserModel({ email });

    UserModel.register(user, password, (err, user) => {
        if (err) {
            return next(new HTTPError(500, err.message));
        }

        const token = JWTService.generateToken(user);

        return res.json({ token });        
    });
}

async function logout(req, res) {
    req.logout()
    res.redirect('/')
}

async function loginNew(req, res) { 
    res.render('pages/login')
}

async function loginCreate(req, res) {
    const token = jwt.sign({ sub: req.user._id }, process.env.SESSION_SECRET)
    res.json(token)
}

module.exports = {
    register,
    logout,
    loginNew,
    loginCreate
}

Пользователь. js

const mongoose = require("mongoose");
const Schema = mongoose.Schema;

// Create Schema
const UserSchema = new Schema({
  email: {
    type: String,
    required: true
  },
  password: {
    type: String,
    required: true
  },
});

const UserModel = mongoose.model("user", UserSchema)

module.exports = { UserModel, UserSchema }

jwt_services . js

const JWT = require("jsonwebtoken");
const expiry = "1d";

function generateToken(user) {
    const token = JWT.sign(
        {
            email: user.email
        },
        process.env.SESSION_SECRET,
        {
            subject: user._id.toString(),
            expiresIn: expiry
        }
    );

    return token;
}

module.exports = {
    generateToken
}

сервер. js

const express = require("express");
const exphbs = require("express-handlebars");
const morgan = require("morgan");
const mongoose = require("mongoose")
const cors = require('cors')

require ("dotenv").config()

const app = express();

app.use(cors({
  origin: process.env.FRONT_END_DOMAIN
}))

app.engine("handlebars", exphbs({defaultLayout: "main"}));
app.set("view engine", "handlebars");

mongoose
  .connect(
    "mongodb://localhost/raw_barbershop",
    { autoIndex: false, useNewUrlParser: true }
  )
  .then(() => console.log("MongoDB successfully connected"))
  .catch(err => console.log(err));

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

const passport = require('./config/passport')

app.use(passport.initialize())
app.use(passport.session())

app.use(morgan("combined"));

app.use(require("./routes"));

app.use(express.static("public"));

app.use(require("./middleware/error_handler_middleware"));

const port = process.env.PORT || 5000;
app.listen(port, () => console.log(`Server up and running on port ${port} !`));

module.exports = app;

1 Ответ

0 голосов
/ 28 января 2020

Вы должны JSON .stringify своих данных при использовании sessionStorage.setItem и JSON .parse при чтении.

Кроме того, в вашем mapStateToProps у вас есть это:

  return {
    token: state.auth.token
  };
};

Но вот так выглядит ваше состояние: state = { token: 'value' }

Убедитесь, что у вас такая же структура.

...