客户没有从我的node.js api那里获得cookie

发布于 2025-01-31 04:03:18 字数 5123 浏览 0 评论 0原文

我已经在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技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。
列表为空,暂无数据
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文