Как решить проблемы с маршрутизацией в приложении аутентификации стека MEVN - PullRequest
0 голосов
/ 19 сентября 2019

Я пытаюсь создать интерфейс аутентификации с помощью Vue.js, Node, Express и MongoDB.До сих пор я успешно включал регистрацию пользователей, когда имя, адрес электронной почты и пароль помещались в базу данных MongoDB при использовании пакета bcrypt для шифрования пароля.Сейчас я пытаюсь разрешить пользователю войти в систему, настроив users.post('/login', (req, res) => {} в users.js, чтобы сравнить адрес электронной почты и пароль, введенные на странице входа, с адресом электронной почты и паролем, хранящимися в базе данных.Если он действителен, то payload возвращается в виде token, который затем помещается в localStorage.Логин, кажется, работает, поскольку панель навигации управляет переходом, чтобы отразить вход в систему.Однако экран не перенаправляет на Profile.vue.Вместо этого экран остается на Login.vue, и в консоли появляется сообщение об ошибке с надписью uncaught (in promise) undefined.Я сузил вопрос до router.push({ name: 'Profile }) в Login.vue.Другими словами, ошибка, кажется, происходит с этой строки.Когда я его удаляю, ошибка исчезает, но мне, очевидно, все еще нужна такая линия, чтобы перенаправить на Profile.vue.Может ли быть проблема с охранником маршрута внизу router.js?Любые рекомендации о том, как правильно настроить охрану маршрута для этого приложения?Мой код ниже.Спасибо!

Login.vue

<template>
    <div class="container">
        <div class="row">
            <div class="col-md-6 mt-5 mx-auto">
                <form v-on:submit.prevent="login">
                    <h1 class="h3 mb-3 font-weight-normal">Please sign in</h1>
                    <div class="form-group">
                        <label for="email">Email Address</label>
                        <input type="email" v-model="email" class="form-control" name="email" placeholder="Enter Email">
                    </div>
                    <div class="form-group">
                        <label for="password">Password</label>
                        <input type="password" v-model="password" class="form-control" name="password" placeholder="Enter Password">
                    </div>
                    <button class="btn btn-lg btn-primary btn-block" type="submit">Sign in</button>
                </form>
            </div>
        </div>
    </div>
</template>

<script>
import axios from 'axios'
import router from '../router'
import EventBus from './EventBus'

export default {
  data () {
    return {
      email: '',
      password: ''
    }
  },

  methods: {
    async login () {
      let res = await axios.post('http://localhost:5000/users/login', {
        email: this.email,
        password: this.password
      })
        await localStorage.setItem('usertoken', res.data)
        router.push({ name: 'Profile' })
        this.email = ''
        this.password = ''
        this.emitMethod()
    },
    emitMethod () {
      EventBus.$emit('logged-in', 'loggedin')
    }
  }
}
</script>

Profile.vue

<template>
    <div class="container">
        <div class="jumbotron mt-5">
            <div class="col-sm-8 mx-auto">
                <h1 class="text-center">PROFILE</h1>
            </div>
            <table class="table col-md-6 mx-auto">
                <tbody>
                    <tr>
                        <td>First Name</td>
                        <td>{{first_name}}</td>
                    </tr>
                    <tr>
                        <td>Last Name</td>
                        <td>{{last_name}}</td>
                    </tr>
                    <tr>
                        <td>Email</td>
                        <td>{{email}}</td>
                    </tr>
                </tbody>
            </table>
        </div>
    </div>
</template>

<script>
import jwtDecode from 'jwt-decode'

export default {
  data () {
    return {
      first_name: '',
      last_name: '',
      email: ''
    }
  },
  created () {
    const token = localStorage.usertoken
    const decoded = jwtDecode(token)
    this.first_name = decoded.first_name,
    this.last_name = decoded.last_name,
    this.email = decoded.email
  }
}
</script>

users.js

const express = require("express")
const users = express.Router()
const cors = require("cors")
const jwt = require("jsonwebtoken")
const bcrypt = require("bcrypt")

const User = require("../models/User")
users.use(cors())

process.env.SECRET_KEY = 'secret'

users.post("/register", (req, res) => {
    const today = new Date()
    const userData = {
        first_name: req.body.first_name,
        last_name: req.body.last_name,
        email: req.body.email,
        password: req.body.password,
        created: today
    }

    User.findOne({
        email: req.body.email
    })
        .then(user => {
            if (!user) {
                bcrypt.hash(req.body.password, 10, (err, hash) => {
                    userData.password = hash
                    User.create(userData)
                        .then(user => {
                            res.json({ status: user.email + ' registered' })
                        })
                        .catch(err => {
                            res.send('error: ' + err)
                        })
                })
            } else {
                res.json({ error: 'User already exists' })
            }
        })
        .catch(err => {
            res.send('error: ' + err)
        })
})

users.post('/login', (req, res) => {
    User.findOne({
        email: req.body.email
    })
        .then(user => {
            if (user) {
                if (bcrypt.compareSync(req.body.password, user.password)) {
                    const payload = {
                        _id: user._id,
                        first_name: user.first_name,
                        last_name: user.last_name,
                        email: user.email
                    }
                    let token = jwt.sign(payload, process.env.SECRET_KEY, {
                        expiresIn: 1440
                    })
                    res.send(token)
                } else {
                    res.json({ error: 'User does not exist' })
                }
            } else {
                res.json({ error: 'User does not exist' })
            }
        })
        .catch(err => {
            res.send('error: ' + err)
        })
})

module.exports = users

router.js

import Vue from 'vue'
import Router from 'vue-router'
import Login from '@/components/Login'
import Register from '@/components/Register'
import Profile from '@/components/Profile'

Vue.use(Router)

const router = new Router({
  mode: 'history',
  routes: [
    {
      path: '/login',
      name: 'Login',
      component: Login
    },
    {
      path: '/register',
      name: 'Register',
      component: Register
    },
    {
      path: '/profile',
      name: 'Profile',
      component: Profile,
      meta: {
        requiresAuth: true
      }
    }
  ]
})

router.beforeEach((to, from, next) => {
  const isLoggedIn = localStorage.getItem("token")
  const requiresAuth = to.matched.some(record => record.meta.requiresAuth)
  if (requiresAuth && !isLoggedIn) next('login')
  else if (!requiresAuth && isLoggedIn) next('profile')
  else next()
})

export default router

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...