Node.js 如何向我的web应用程序的用户显示不同的内容?梅恩栈

Node.js 如何向我的web应用程序的用户显示不同的内容?梅恩栈,node.js,reactjs,express,mongoose,Node.js,Reactjs,Express,Mongoose,我正在尝试制作一个投票应用程序,每个用户只能投票一次。为了做到这一点,我保存了已经投票的用户的ip,并将其与使用该应用程序的用户的ip进行比较。因此,如果他的ip与数据库中已经存在的ip匹配,他将得到一个屏幕,显示他不能再次投票。 问题是,如果一个用户投票,其他所有用户都会在屏幕上说他们不能投票 这是后端代码,用于获取用户ip和数据库中的所有ip,并在投票时发布ip: const express = require("express"); const router = express.Route

我正在尝试制作一个投票应用程序,每个用户只能投票一次。为了做到这一点,我保存了已经投票的用户的ip,并将其与使用该应用程序的用户的ip进行比较。因此,如果他的ip与数据库中已经存在的ip匹配,他将得到一个屏幕,显示他不能再次投票。 问题是,如果一个用户投票,其他所有用户都会在屏幕上说他们不能投票

这是后端代码,用于获取用户ip和数据库中的所有ip,并在投票时发布ip:

const express = require("express");
const router = express.Router();
const ipify = require("ipify");
const mongoose = require("mongoose");
const internalIp = require("internal-ip");

const ipModel = require("../../models/Ip");

// @route   GET api/ip
// @desc    obtener todas las ip de la db
// @access  public
router.get("/", (req, res) => {
  ipModel
    .find()
    .then(ip => {
      res.status(200).json(ip);
    })
    .catch(err => res.status(404).json(err));
});

// @route   POST api/ip
// @desc    Guardar la ip en la db
// @access  public
router.post("/", (req, res) => {
  internalIp
    .v4()
    .then(miip => {
      ipModel
        .findOne({ ip: miip })
        .then(laip => {
          if (laip) {
            return res
              .status(400)
              .json({ ip: "Su voto se ha realizado exitosamente" });
          } else {
            const newIp = new ipModel({
              ip: miip
            });
            newIp.save().then(ip => res.json(newIp));
          }
        })
        .catch(err => res.status(404).json(err));
    })
    .catch(err => res.json(err));
});

// @route   GET api/ip/miip
// @desc    Guardar la ip en la db
// @access  public
router.get("/miip", (req, res) => {
  internalIp
    .v4()
    .then(miip => {
      res.status(200).json(miip);
    })
    .catch(err => res.json(err));
});

module.exports = router;
这是管理前端投票逻辑的组件的代码:

import React, { Component } from "react";
import { Redirect } from "react-router-dom";
import { Container, ListGroup, ListGroupItem, Button } from "reactstrap";
import { CSSTransition, TransitionGroup } from "react-transition-group";
import axios from "axios";

class Votos extends Component {
  constructor() {
    super();
    this.state = {
      carrozas: [],
      ipRegistradas: [],
      miIp: null,
      goToVotos: true
    };
    this.votar = this.votar.bind(this);
  }

  componentDidMount() {
    axios
      .get("/api/ip")
      .then(ips => {
        this.setState(prevState => ({
          ipRegistradas: [...prevState.ipRegistradas, ...ips.data]
        }));
      })
      .catch(err => console.log(err));

    axios
      .get("/api/carrozas")
      .then(carrozasdb => {
        this.setState(prevState => ({
          carrozas: [...prevState.carrozas, ...carrozasdb.data]
        }));
      })
      .catch(err => console.log(err));

    axios
      .get("/api/ip/miip")
      .then(miip => {
        this.setState({
          miIp: miip.data
        });
      })
      .catch(err => console.log(err));
  }

  shouldRedirect() {
    for (var i = 0; i < this.state.ipRegistradas.length; i++) {
      if (this.state.ipRegistradas[i].ip === this.state.miIp) {
        this.setState({
          goToVotos: false
        });
      }
    }
  }

  votar(nom) {
    axios.post("/api/votos", { nombre: nom });
    axios.post("/api/ip");
  }

  render() {
    const { carrozas } = this.state;
    this.shouldRedirect();

    if (this.state.goToVotos === true) {
      return (
        <Container>
          <h3
            style={{
              display: "flex",
              justifyContent: "center",
              alignItems: "center"
            }}
          >
            Votá la mejor carroza...
          </h3>
          <ListGroup>
            <TransitionGroup className="carrozas">
              {carrozas.map(({ _id, nombre, curso }) => (
                <CSSTransition key={_id} timeout={500} classNames="fade">
                  <ListGroupItem
                    style={{
                      display: "flex",
                      justifyContent: "spaceAround"
                    }}
                  >
                    <Button
                      className="votar-btn"
                      color="primary"
                      size="sm"
                      onClick={() => {
                        this.votar(nombre);
                        this.props.history.push("/votoexitoso");
                      }}
                    >
                      Votar
                    </Button>
                    "{nombre}"
                    <p
                      style={{
                        marginLeft: "5rem"
                      }}
                    >
                      {curso}
                    </p>
                  </ListGroupItem>
                </CSSTransition>
              ))}
            </TransitionGroup>
          </ListGroup>
        </Container>
      );
    } else {
      return <Redirect to="votoexitoso" />;
    }
  }
}

export default Votos;
import React,{Component}来自“React”;
从“react router dom”导入{Redirect};
从“reactstrap”导入{Container、ListGroup、ListGroupItem、Button};
从“react transition group”导入{CSTranslation,TransitionGroup};
从“axios”导入axios;
类Votos扩展了组件{
构造函数(){
超级();
此.state={
卡罗萨斯:[],
IPDAS:[],
miIp:null,
戈托沃托斯:是的
};
this.votar=this.votar.bind(this);
}
componentDidMount(){
axios
.get(“/api/ip”)
。然后(ips=>{
this.setState(prevState=>({
ipRegistradas:[…prevState.ipRegistradas,…ips.data]
}));
})
.catch(err=>console.log(err));
axios
.get(“/api/carrozas”)
.然后(carrozasdb=>{
this.setState(prevState=>({
carrozas:[…prevState.carrozas,…carrozasdb.data]
}));
})
.catch(err=>console.log(err));
axios
.get(“/api/ip/miip”)
。然后(miip=>{
这是我的国家({
miIp:miIp.data
});
})
.catch(err=>console.log(err));
}
shouldRedirect(){
for(var i=0;i(
{
这是votar(nombre);
this.props.history.push(“/votoexitoso”);
}}
>
伏塔
“{nombre}”

{curso}

))} ); }否则{ 返回; } } } 导出默认Votos;
内部ip
提供您的服务器ip地址。要获取客户端IP地址,您可以使用
request.connection.remoteAddress
request.headers['x-forwarded-for']
(如果服务器位于代理之后)

router.post(“/”,(req,res)=>{
const ip=req.connection.remoteAddress;
...

使用客户端IP地址而不是服务器IP地址如何解决问题?好的,当用户投票时,您将其IP地址存储在数据库中,并且只有在数据库中找不到其IP地址时才允许投票(对吗?)。如果您使用服务器IP地址,您实际上是在将您的服务器地址与以前存储的服务器地址进行比较,因此每个人都会收到“无法投票”消息。我已经尝试了您的解决方案,并且效果良好。谢谢。但我现在有另一个问题。每次在电话中使用应用程序投票时,数据库中都会保存一个不同的IP地址对于相同的设备,它总是允许通用的,IP地址不是识别用户身份的可靠方法,它们是动态的并且可以随着时间而改变。如果您需要100%确定该用户以前没有投票,请考虑使用另一种方法,例如注册。注册。如果我使用cookies而不是IP地址或注册方法?