使用Jwt和nodejs进行身份验证

时间:2019-03-27 15:16:16

标签: node.js authentication vue.js jwt

我有两个问题。

1。当我尝试使用JWT令牌和Nodejs进行身份验证时,我能够登录和注销,但是当我登录后刷新页面时,导航栏就会消失。

  1. 当我未登录登录页面时,当我单击它未重定向到该页面时,我提供了指向注册页面的链接。当我不让导航栏进行身份验证时,就会发生这种情况。

这是登录页面

<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" required>
                    </div>
                    <div class="form-group">
                        <label for="password">Password</label>
                        <input type="password" v-model="password" class="form-control" name="email" placeholder="Enter Password" required>
                    </div>
                    <button class="btn btn-lg btn-danger btn-block" type="submit">Login</button>
                    <a href="/register">New User? Register here</a>
                </form>
            </div>
        </div>
    </div>
</template>

<script>
import axios from 'axios'
import router from '../router'
import EventBus from './EventBus'
import Navbar from '@/components/Navbar'
export default {
  components: {Navbar},
  data () {
    return {
      email: '',
      password: ''
    }
  },

  methods: {
    login () {
      axios.post('http://localhost:5000/users/login',
        {
          email: this.email,
          password: this.password
        }).then((res) => {
        localStorage.setItem('usertoken', res.data)
        this.email = ''
        this.password = ''
        if (res) {
        this.emitMethod()
        router.push({ name: 'profile' })
        } 
      }).catch(err => {
        console.log(err, alert('User doesnot exist'))

      })
    },
    emitMethod () {
      EventBus.$emit('logged-in', 'loggedin')
    }
  }
}
</script>

这是我用于注销的脚本

logout () {
      localStorage.removeItem('usertoken')
    }

用户路线

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

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

process.env.SECRET_KEY = 'secret'

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

    User.findOne({
        where: {
            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({
        where: {
            email: req.body.email
        }
    })
        .then(user => {
            if (user) {
                if (bcrypt.compareSync(req.body.password, user.password)) {
                    let token = jwt.sign(user.dataValues, process.env.SECRET_KEY, {
                        expiresIn: 1440
                    })
                    res.send(token)
                }
            } else {
                res.status(400).json({ error: 'User does not exist' })
            }
        })
        .catch(err => {
            res.status(400).json({ error: err })

        })
})

users.get('/profile', (req, res) => {
    var decoded = jwt.verify(req.headers['authorization'], process.env.SECRET_KEY)

    User.findOne({
        where: {
            userId: decoded.userId
        }
    })
    .then(user => {
        if (user) {
            res.json(user)
        } else {
            res.send('User does not exist')
        }
    })
    .catch(err => {
        res.send('error: ' + err)
    })
})

users.put("/:userId", (req, res) => {
        if (!req.body.firstName,
            !req.body.lastName,
            !req.body.city,
            !req.body.cycle,
            !req.body.biography) {
            res.status(400)
            res.json({
                error: "Bad Data"
            })
        } else {
            User.update(
                { firstName: req.body.firstName,
                  lastName: req.body.lastName,
                  city: req.body.city,
                  cycle: req.body.cycle,
                  biography: req.body.biography
                },
                { where: { userId: req.params.userId } }
            )
            .then(() => {
               res.send("Contact updated")
            })
            .error(err => res.send(err))
        }
    })

module.exports = users

1 个答案:

答案 0 :(得分:0)

我不确定您正在构建的Web应用是只是为了娱乐还是打算在生产中使用它,如果是这样,我建议您不要使用localStorage保存令牌。 JWT需要存储在用户浏览器内部的安全位置。

如果将其存储在localStorage中,则页面内的任何脚本都可以访问它(听起来很糟糕,因为XSS攻击可以使外部攻击者访问令牌)。

不要将其存储在本地存储(或会话存储)中。如果您包含在页面中的第3部分脚本中的任何一个遭到破坏,它就可以访问您所有用户的令牌。

JWT需要存储在HttpOnly cookie内,这是一种特殊的cookie,仅通过HTTP请求发送到服务器,并且永远无法通过浏览器中运行的JavaScript进行访问(读取或写入)。

来源:

  1. https://auth0.com/docs/security/store-tokens
  2. https://logrocket.com/blog/jwt-authentication-best-practices/
  3. https://blog.usejournal.com/sessionless-authentication-withe-jwts-with-node-express-passport-js-69b059e4b22c

现在回到原来的问题,我明白了

import Navbar from '@/components/Navbar'

但是我不是在模板中使用它,也可以发布遇到问题的vue组件吗?