客户没有从我的node.js api那里获得cookie
我已经在Node.js/Express中与JWT API进行了身份验证,然后在Heroku上运行。 当用户登录时,服务器通过cookie-parser创建cookie并将其发送给客户端。 以下是从server.js的代码
const express = require('express');
const jwt = require('jsonwebtoken');
const cookieParser = require('cookie-parser');
const cors = require('cors');
const path = require('path');
const bcrypt = require('bcrypt');
const PORT = process.env.PORT || 3000;
const serveStatic = require('serve-static');
require('dotenv').config();
const mongoose = require('mongoose');
const { User, Posts } = require(path.join(__dirname, './model.js'));
const mongoString = process.env.DATABASE_URL;
const JWT_SECRET = process.env.JWT_SECRET;
const { verifyToken, checkUser } = require(path.join(__dirname, './auth.js'));
const app = express();
//Middlewares
app.use(
cors({
credentials: true,
origin: true,
})
);
app.use(express.json());
app.use(cookieParser());
//Connect to Database
mongoose.connect(mongoString);
const db = mongoose.connection;
db.on('error', (err) => {
console.log(err);
});
db.once('connected', () => {
console.log('----Database Connected----\n');
});
//functions
const maxAge = 3 * 24 * 60 * 60;
const createToken = (id) => {
return jwt.sign({ id }, JWT_SECRET, {
expiresIn: maxAge,
});
};
// AUTH ROUTES
app.get('*', checkUser);
app.get('/', checkUser, (req, res) => {
res.json({ status: 'success' });
});
app.post('/api/register', async (req, res) => {
const salt = await bcrypt.genSalt();
try {
const user = await User.create(
new User({
username: req.body.username,
email: req.body.email,
city: req.body.city,
password: await bcrypt.hash(req.body.password, salt),
})
);
const token = createToken(user._id);
res.cookie('jwt', token, {
maxAge: maxAge * 1000,
secure: true,
});
res.status(201).json(user);
console.log(user);
} catch (err) {
console.log(err);
res.json(err);
}
});
app.post('/api/login', async (req, res) => {
try {
const { email, password } = req.body;
const user = await User.findOne({ email }).lean();
if (!user) {
return res.send({
status: 'error',
error: 'Invalid email',
});
}
if (await bcrypt.compare(password, user.password)) {
const token = createToken(user._id);
res.cookie('jwt', token, { secure: true, maxAge: maxAge * 1000 });
res.status(200).send({ status: 'ok', token: token });
console.log(user._id + ' logged in successfully');
return;
}
return res.send({ status: 'error', error: 'Invalid password' });
} catch (err) {
console.log(err);
}
});
app.get('/api/home', verifyToken, (req, res) => {
res.send(res.locals.user);
});
app.get('/api/logout', (req, res) => {
try {
res.cookie('jwt', '', { maxAge: 1 });
res.status(200).send({ status: 'ok' });
} catch (err) {
res.send(err);
}
});
//POSTS ROUTES
app.post('/api/posts', verifyToken, checkUser, async (req, res) => {
try {
const post = await Posts.create(
new Posts({
postBody: req.body.postBody,
city: req.body.city,
author: res.locals.user.id,
})
);
res.status(200).json(post);
console.log('====New Post=====');
} catch (err) {
res.status(400).send({ message: err.message });
}
});
app.get('/api/posts', verifyToken, async (req, res) => {
try {
const data = await Posts.find();
res.send({ user: res.locals.user, data: data });
} catch (err) {
res.json({ message: err.message });
}
});
app.get('/api/posts/:city', verifyToken, async (req, res) => {
try {
const data = await Posts.find({ city: req.params.city });
res.json(data);
res.send(res.locals.user);
} catch (err) {
res.json({ message: err.message });
}
});
//run server
app.listen(PORT, () => {
console.log(`Server running on ${PORT}...\n`);
});
,对于前端,我使用vue.js在firebase上运行。
这是登录的脚本部分。
<script>
/* eslint-disable */
import axios from 'axios';
export default {
name: 'Login',
data() {
return {
email: '',
password: '',
error: '',
};
},
methods: {
async onSubmit() {
if (!this.email || this.password.length < 6) {
this.error = 'vale kati';
return;
}
await axios
.post(
'https://thelostpet.herokuapp.com/api/login',
{
email: this.email,
password: this.password,
},
{ withCredentials: true }
)
.then((res) => {
console.log(res.data.token);
if (res.data.status == 'error') {
this.error = res.data.error;
}
if (res.data.status == 'ok') {
this.$router.push('/home');
}
})
.catch((err) => {
console.log(err);
});
},
},
};
</script>
当我尝试从login.vue登录时,它在firebase上登录时,浏览器不会保存从API创建的cookie。
但是,当我通过https://thelostpet.herokuapp.com/api/login
从Postman发出发布请求时,Cookie将保存在Postman上。
谢谢你!
I have made an authentication with jwt api in node.js/express and i run it on heroku.
When a user logged in, server create a cookie via cookie-parser and send it to the client.
Below is the code from server.js
const express = require('express');
const jwt = require('jsonwebtoken');
const cookieParser = require('cookie-parser');
const cors = require('cors');
const path = require('path');
const bcrypt = require('bcrypt');
const PORT = process.env.PORT || 3000;
const serveStatic = require('serve-static');
require('dotenv').config();
const mongoose = require('mongoose');
const { User, Posts } = require(path.join(__dirname, './model.js'));
const mongoString = process.env.DATABASE_URL;
const JWT_SECRET = process.env.JWT_SECRET;
const { verifyToken, checkUser } = require(path.join(__dirname, './auth.js'));
const app = express();
//Middlewares
app.use(
cors({
credentials: true,
origin: true,
})
);
app.use(express.json());
app.use(cookieParser());
//Connect to Database
mongoose.connect(mongoString);
const db = mongoose.connection;
db.on('error', (err) => {
console.log(err);
});
db.once('connected', () => {
console.log('----Database Connected----\n');
});
//functions
const maxAge = 3 * 24 * 60 * 60;
const createToken = (id) => {
return jwt.sign({ id }, JWT_SECRET, {
expiresIn: maxAge,
});
};
// AUTH ROUTES
app.get('*', checkUser);
app.get('/', checkUser, (req, res) => {
res.json({ status: 'success' });
});
app.post('/api/register', async (req, res) => {
const salt = await bcrypt.genSalt();
try {
const user = await User.create(
new User({
username: req.body.username,
email: req.body.email,
city: req.body.city,
password: await bcrypt.hash(req.body.password, salt),
})
);
const token = createToken(user._id);
res.cookie('jwt', token, {
maxAge: maxAge * 1000,
secure: true,
});
res.status(201).json(user);
console.log(user);
} catch (err) {
console.log(err);
res.json(err);
}
});
app.post('/api/login', async (req, res) => {
try {
const { email, password } = req.body;
const user = await User.findOne({ email }).lean();
if (!user) {
return res.send({
status: 'error',
error: 'Invalid email',
});
}
if (await bcrypt.compare(password, user.password)) {
const token = createToken(user._id);
res.cookie('jwt', token, { secure: true, maxAge: maxAge * 1000 });
res.status(200).send({ status: 'ok', token: token });
console.log(user._id + ' logged in successfully');
return;
}
return res.send({ status: 'error', error: 'Invalid password' });
} catch (err) {
console.log(err);
}
});
app.get('/api/home', verifyToken, (req, res) => {
res.send(res.locals.user);
});
app.get('/api/logout', (req, res) => {
try {
res.cookie('jwt', '', { maxAge: 1 });
res.status(200).send({ status: 'ok' });
} catch (err) {
res.send(err);
}
});
//POSTS ROUTES
app.post('/api/posts', verifyToken, checkUser, async (req, res) => {
try {
const post = await Posts.create(
new Posts({
postBody: req.body.postBody,
city: req.body.city,
author: res.locals.user.id,
})
);
res.status(200).json(post);
console.log('====New Post=====');
} catch (err) {
res.status(400).send({ message: err.message });
}
});
app.get('/api/posts', verifyToken, async (req, res) => {
try {
const data = await Posts.find();
res.send({ user: res.locals.user, data: data });
} catch (err) {
res.json({ message: err.message });
}
});
app.get('/api/posts/:city', verifyToken, async (req, res) => {
try {
const data = await Posts.find({ city: req.params.city });
res.json(data);
res.send(res.locals.user);
} catch (err) {
res.json({ message: err.message });
}
});
//run server
app.listen(PORT, () => {
console.log(`Server running on ${PORT}...\n`);
});
Now, for front-end i use Vue.js that its running on Firebase.
Here is the script part of Login.Vue
<script>
/* eslint-disable */
import axios from 'axios';
export default {
name: 'Login',
data() {
return {
email: '',
password: '',
error: '',
};
},
methods: {
async onSubmit() {
if (!this.email || this.password.length < 6) {
this.error = 'vale kati';
return;
}
await axios
.post(
'https://thelostpet.herokuapp.com/api/login',
{
email: this.email,
password: this.password,
},
{ withCredentials: true }
)
.then((res) => {
console.log(res.data.token);
if (res.data.status == 'error') {
this.error = res.data.error;
}
if (res.data.status == 'ok') {
this.$router.push('/home');
}
})
.catch((err) => {
console.log(err);
});
},
},
};
</script>
When I try to login from Login.vue, that its ruuning on Firebase, the browser doesn't save the cookie that it created from the api.
BUT when I make a post request on https://thelostpet.herokuapp.com/api/login
from postman, the cookie is saved on postman.
Thank you!
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
![扫码二维码加入Web技术交流群](/public/img/jiaqun_03.jpg)
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论