node.js - 使用 Jwt 和 nodejs 进行身份验证
问题描述
我有两个问题。
1.当我尝试使用 JWT 令牌和 Nodejs 执行身份验证时,我可以登录和注销,但是当我登录时,如果我刷新页面,导航栏就会消失。
- 当我没有在登录页面登录时,当我单击它没有重定向到该页面时,我给出了一个指向注册页面的链接。当我不给导航栏进行身份验证时,就会发生这种情况。
这是登录页面
<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
解决方案
我不确定您正在构建的 Web 应用程序是否只是为了好玩,或者您打算在生产中使用它,如果是这样,我建议您不要使用 localStorage 来保存令牌。JWT 需要存储在用户浏览器内的安全位置。
如果将其存储在 localStorage 中,则页面内的任何脚本都可以访问它(这听起来就像 XSS 攻击可以让外部攻击者访问令牌一样糟糕)。
不要将其存储在本地存储(或会话存储)中。如果您包含在页面中的第 3 部分脚本中的任何一个被泄露,它可以访问您所有用户的令牌。
JWT 需要存储在 HttpOnly cookie 中,这是一种特殊类型的 cookie,仅在 HTTP 请求中发送到服务器,并且永远无法从浏览器中运行的 JavaScript 访问(无论是读取还是写入)。
资源:
- https://auth0.com/docs/security/store-tokens
- https://logrocket.com/blog/jwt-authentication-best-practices/
- https://blog.usejournal.com/sessionless-authentication-withe-jwts-with-node-express-passport-js-69b059e4b22c
现在回到原来的问题,我明白了
import Navbar from '@/components/Navbar'
但是我没有在模板中使用它,您也可以发布您遇到问题的 vue 组件吗?
推荐阅读
- ios - 如何在响应所有设备的 react-native 应用程序中设置 marginLeft 和 marginRight
- python - Python 中的正则表达式,用于检测整数、浮点数或科学记数法中的数字
- python - 圆上的非最大值抑制
- javascript - 为什么在此反应代码中释放外部 div 时不会触发 mouseup 事件(使用 window.addEventListener)
- android - recyclerview 无法同步或创建
- python - 使用 opencv_createsamples 时出现“无效的背景描述文件”
- sdl-2 - 我需要设置哪些标志才能将 libwebp-1.0.0 与提供的外部库静态链接?
- node.js - Express、Passport-Google、React - 维护正确的会话信息
- activemq-artemis - 无法运行 Artemis 附带的示例
- sql - 使用 CAST 对 XML 进行 DISTINCT