You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何正确实现用户最后登录时间的前后端处理?含React展示需求

登录后更新并展示用户最后登录时间的前后端实现方案

后端(Node.js + Mongoose)修正方案

1. 用户Schema修正

你的Schema中lastLogin的默认值写法有问题:Date.now()会在Schema定义时就执行一次,新创建用户时不会自动生成当前时间。需要改为不带括号的Date.now,让Mongoose在创建文档时动态生成时间:

const userSchema = new Schema(
  {
    name: { type: String },
    email: { type: String, unique: true},
    password: { type: String },
    status: {type: String, enum:["Active", "Blocked"], default:"Active"},
    token: { type: String },
    // 修正:去掉括号,实现动态生成当前时间
    lastLogin: { type: Date, default: Date.now },
  },
  { timestamps: true }
);  

2. 登录路由逻辑修正

原登录代码存在3个核心问题:更新lastLogin的条件错误、未将修改持久化到数据库、HTTP状态码不规范。以下是修正后的代码:

userRouter.post("/login", async (req, res, next) => {
  try {
    const { email, password } = req.body;
    // 参数不全返回400(客户端错误),而非204
    if (!(email && password)) {
      return res.status(400).send({ msg: "所有字段均为必填项!" });
    }

    const user = await UsersModel.findOne({ email });
    // 用户不存在返回404
    if (!user) {
      return res.status(404).send({ msg: "该邮箱对应的用户不存在!" });
    }

    // 密码验证失败返回401(未授权)
    const isPasswordValid = await bcrypt.compare(password, user.password);
    if (!isPasswordValid) {
      return res.status(401).send({ msg: "密码错误!" });
    }

    // 生成JWT token
    const accessToken = await JWTAuthenticate(user);
    
    // 精准更新当前登录用户的token和lastLogin
    const updatedUser = await UsersModel.findByIdAndUpdate(
      user._id,
      { token: accessToken, lastLogin: new Date() },
      { new: true } // 返回更新后的完整用户数据
    );

    // 移除敏感字段后返回前端
    const safeUser = { ...updatedUser.toObject() };
    delete safeUser.password;
    res.status(200).send(safeUser);

  } catch (error) {
    next(error);
  }
});

关键改进点:

  • 用findByIdAndUpdate精准定位当前用户,确保lastLogin更新到正确的文档
  • 移除password字段后再返回,避免敏感信息泄露
  • 规范各场景的HTTP状态码,符合RESTful规范

前端(React)展示方案

1. 登录成功后存储用户信息

登录接口调用成功后,将包含lastLogin的用户信息存储到localStorage或状态管理工具:

const handleLogin = async (email, password) => {
  try {
    const res = await fetch('/api/users/login', {
      method: 'POST',
      headers: { 'Content-Type': 'application/json' },
      body: JSON.stringify({ email, password })
    });
    const data = await res.json();
    if (res.ok) {
      localStorage.setItem('currentUser', JSON.stringify(data));
      window.location.href = '/user-list';
    } else {
      alert(data.msg);
    }
  } catch (err) {
    console.error('登录失败:', err);
  }
};

2. 获取用户列表并渲染表格

在用户列表页面,调用后端接口获取所有用户数据,格式化lastLogin后渲染到表格:

import { useEffect, useState } from 'react';

const UserTable = () => {
  const [users, setUsers] = useState([]);

  useEffect(() => {
    const fetchUsers = async () => {
      try {
        const res = await fetch('/api/users');
        const data = await res.json();
        setUsers(data);
      } catch (err) {
        console.error('获取用户列表失败:', err);
      }
    };
    fetchUsers();
  }, []);

  // 格式化日期为中文可读格式
  const formatLastLogin = (dateString) => {
    if (!dateString) return '无登录记录';
    const date = new Date(dateString);
    return date.toLocaleString('zh-CN', {
      year: 'numeric',
      month: '2-digit',
      day: '2-digit',
      hour: '2-digit',
      minute: '2-digit'
    });
  };

  return (
    <table border="1" cellpadding="8" cellspacing="0">
      <thead>
        <tr>
          <th>用户名</th>
          <th>邮箱</th>
          <th>状态</th>
          <th>最后登录时间</th>
        </tr>
      </thead>
      <tbody>
        {users.map(user => (
          <tr key={user._id}>
            <td>{user.name}</td>
            <td>{user.email}</td>
            <td>{user.status}</td>
            <td>{formatLastLogin(user.lastLogin)}</td>
          </tr>
        ))}
      </tbody>
    </table>
  );
};

export default UserTable;

3. 额外注意事项

  • 后端用户列表接口需确保返回lastLogin字段,可通过UsersModel.find({}, '-password')过滤敏感字段
  • 若需要更复杂的日期格式化,可使用dayjs等第三方库简化操作
  • 若使用状态管理工具(如Redux、Zustand),需同步更新用户信息,保证表格数据实时性

内容的提问来源于stack exchange,提问作者user18986944

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.18 17:20:56