首页 > 其他分享 >前端如何检测用户登录状态是否过期?

前端如何检测用户登录状态是否过期?

时间:2024-10-31 12:18:12浏览次数:3  
标签:令牌 const 登录 过期 前端 用户 token

在前端开发中 , 判断用户登录状态是否过期是一个常见的需求。尤其是在复杂的场景中 , 准确判断用户登录状态是否过期是保障用户体验的关键环节。这一过程涉及到服务器与前端之间的紧密协作 , 以及多种技术手段的综合运用 , 还是蛮有挑战性的。

判断登录过期的主要方法有: 检查令牌有效期 , 定时轮询服务器 , 全局请求拦截器 , 利用web存储中的时间戳

一、检查令牌有效期

对于包含有效期信息的令牌(如 JWT 中的exp字段),前端可以在每次发送请求之前对令牌进行检查。以下是一个简单的检查 JWT 令牌有效期的函数示例(使用jwt-decode库来解析 JWT):

import jwt_decode from 'jwt-decode';

function checkTokenValidity(token) {
    try {
        const decodedToken = jwt_decode(token);
        const currentTime = Date.now() / 1000; // 获取当前时间(以秒为单位)
        if (decodedToken.exp < currentTime) {
            console.log('令牌已过期(令牌有效期检查)');
            return false;
        }
        return true;
    } catch (error) {
        console.log('令牌解析出错:', error);
        return false;
    }
}

// 在发送请求前调用此函数检查令牌
const token = localStorage.getItem('token');
if (checkTokenValidity(token)) {
    // 令牌有效,继续发送请求
    // 这里假设使用`axios`发送请求
    axios.get('/api/data');
} else {
    console.log('登录状态可能已过期,需处理');
    // 处理登录过期情况,如提示用户重新登录
}

二、定时轮询服务器

轮询服务器状态是一种主动检查令牌是否有效的方法。前端可以定期发送请求到服务器,检查令牌是否仍然有效。

1. 定时轮询

设置一个定时器,每隔一定时间发送请求到服务器,检查令牌状态:

function checkTokenStatus() {
    axios.get('/auth/check')
        .then(response => {
            if (!response.data.valid) {
                // 令牌无效,执行登出逻辑
                logout();
            }
        })
        .catch(error => {
            // 网络错误或其他问题,执行登出逻辑
            logout();
        });
}
setInterval(checkTokenStatus, 15 * 60 * 1000); // 每15分钟检查一次

2.优化轮询频率

需求背景: 在企业级应用中,可能会有大量用户同时在线,频繁的过期检测操作(如定时轮询)会对系统性能造成过大的负担。因此,需要采用高效的过期检测机制,例如优化轮询的频率,或者采用更智能的令牌有效期检查算法,减少不必要的检测次数。

为了减少对服务器的压力,可以根据用户的操作频率调整轮询频率。例如,在用户活跃时频繁检查,在用户长时间没有操作时减少检查频率。

let lastActivityTime = Date.now();
document.addEventListener('mousemove', () => lastActivityTime = Date.now());
document.addEventListener('keydown', () => lastActivityTime = Date.now());

setInterval(() => {
    if (Date.now() - lastActivityTime < 5 * 60 * 1000) { // 用户5分钟内有操作
        checkTokenStatus();
    }
}, 15 * 60 * 1000);

这种方法可以在确保安全性的同时减少对服务器的压力。

三、全局请求拦截器

前端在发送请求时,可以通过检查服务器的响应状态码来判断登录是否过期。通常,服务器会返回401未授权状态码表示令牌无效或过期。

1. 捕获401状态码

axios.interceptors.response.use(response => {
    return response;
}, error => {
    if (error.response.status === 401) {
        // 令牌无效或过期,执行登出逻辑
        logout();
    }
    return Promise.reject(error);
});

2.弹出登录提示

当捕获到401状态码时 , 可以弹出登录提示 , 引导用户重新登录:

function logout() {
    // 清除本地存储的令牌
    removeToken();
    // 弹出登录提示
    alert('登录已过期,请重新登录');
    // 跳转到登录页面
    window.location.href = '/login';
}

这种方法可以确保前端在令牌过期时及时响应,提高了系统的安全性。

四、利用web中的持久化存储

前端可以在登录成功时将令牌的有效期时间戳保存到Web存储(如localStorage或sessionStorage),并在每次请求前检查时间戳是否过期。

1.保存时间戳

在用户登录成功后 , 将令牌和有效期时间戳保存到 localStorage中:

function saveToken(token, expiresIn) {
    const expirationTime = Date.now() + expiresIn * 1000;
    localStorage.setItem('token', token);
    localStorage.setItem('tokenExpiration', expirationTime);
}

2.检查时间戳

在每次请求前,检查当前时间是否超过保存的时间戳:

function isTokenExpired() {
    const expirationTime = localStorage.getItem('tokenExpiration');
    return Date.now() >= expirationTime;
}

如果时间戳过期,则提示用户重新登录:

axios.interceptors.request.use(config => {
    if (isTokenExpired()) {
        // 令牌过期,执行登出逻辑
        logout();
    } else {
        const token = localStorage.getItem('token');
        config.headers['Authorization'] = `Bearer ${token}`;
    }
    return config;
}, error => {
    return Promise.reject(error);
});

特定场景中的优化方案

前面都是检测用户登录状态的方法 , 这个时候 产品经理提出一个需要优化的点:

需求背景: 在业务流程中,用户可能正在进行重要的操作(如填写复杂的表单、进行数据分析等)。当登录状态过期时,应尽量避免突然中断用户操作,如在不影响用户当前输入的情况下弹出提示框,引导用户重新登录。

那我们如何实现这个需求呢? 答案是--------优雅降级

当检测到登录状态过期时,为了避免给用户带来突兀的体验,我们需要采用优雅降级的方式。例如,可以通过模态框提示用户登录过期信息,并允许用户重新登录,同时要保留当前页面的状态。以下是一个使用 React.js 实现的简单示例(使用react-bootstrap的模态框组件):

首先,确保项目中已经安装了react-bootstrapreact-router-dom库。

import React, { useState } from 'react';
import { Button, Modal } from 'react-bootstrap';
import { useHistory } from 'react-router-dom';

const LoginExpiredModal = () => {
    const [dialogVisible, setDialogVisible] = useState(false);
    const history = useHistory();
    // 这里模拟存储当前页面的一些状态信息,比如表单数据等
    const currentPageState = {
        formData: { name: 'John', age: 30 }
    };

    const showModal = () => {
        setDialogVisible(true);
    };

    const handleClose = () => {
        // 将当前页面状态存储到localStorage中
        localStorage.setItem('pageState', JSON.stringify(currentPageState));
        // 重定向到登录页面
        history.push('/login');
    };

    return (
        <div>
            <Button onClick={showModal}>模拟触发登录过期提示</Button>
            <Modal show={dialogVisible} onHide={handleClose}>
                <Modal.Header closeButton>
                    <Modal.Title>登录过期</Modal.Title>
                </Modal.Header>
                <Modal.Body>
                    <p>您的登录已过期,请重新登录。</p>
                </Modal.Body>
            </Modal>
        </div>
    );
};

export default LoginExpiredModal;

标签:令牌,const,登录,过期,前端,用户,token
From: https://blog.csdn.net/Mz0127/article/details/143377054

相关文章

  • java Web 时间LocalDateTime 输出到前端格式化
    格式化时间返回到前端 packagecom.za.edu.config;importcom.fasterxml.jackson.databind.DeserializationFeature;importcom.fasterxml.jackson.databind.ObjectMapper;importcom.fasterxml.jackson.databind.module.SimpleModule;importcom.fasterxml.jackson.datab......
  • 24h搜书zlibrary中文官网登录入口及客户端app
    24h搜书是什么24小时搜书是一个提供在线搜索和下载电子书的平台,它允许用户根据书名、作者、出版社等信息搜索电子书,并支持多种电子书格式,如azw3、mobi、epub、pdf等。这个平台以其丰富的电子书资源和便捷的搜索功能而受到用户欢迎,用户可以免登录直接下载所需的电子书。24小时搜......
  • 关于Web前端使用JavaScript常见的数据类型处理小技巧
    1.1获取字符串长度  如果想获取这个字符串的长度,也就是它里面有多少个字符,可以使用 length 属性:consts="HelloWorld";console.log(s.length)1.2 转换大小写toUpperCase() 方法可以将字母全部大写consts="HelloWorld";console.log(s.toLowerCase());......
  • HTML5期末大作业:HTM+CSS+JS仿安徽开放大学官网(web前端网页制作课作业)
    ......
  • 自创一种前端语言,能否替代js,以实现代码加密?
    js加密,是前端很常见的需求。常见的方法是用jshaman、jsjiami.online等进行js代码混淆加密。是否有其它的方案呢?比如:我们能否自己开发一种前端浏览器语言,取代js(将js代码,转化为自己独特的语言,从而让他人看不懂),以此实现变相的js代码加密。以此思路,下面进行尝试和研究。有一个符合这个......
  • QQ空间协议从登录到实现各种功能完整代码(专栏完结)
    QQ协议扫码登录、账号密码登录、说说、评论、点赞、访客、留言实现及代码——专栏完结本文章为包和实现代码汇总,每个功能的具体实现和分析过程请看本专栏对应的文章,不管扣代码还是分析都是超详细的教程本文为本专栏的完结汇总文章一、扫码登录 扫码登录流程:发送获取二......
  • 【Web前端】JavaScript 对象原型与继承机制
    JavaScript是一种动态类型的编程语言,其核心特性之一就是对象和原型链。理解原型及其工作机制对于掌握JavaScript的继承和对象关系非常重要。什么是原型每个对象都有一个内部属性 ​​[[Prototype]]​​​,这个属性指向创建该对象的构造函数的原型对象。这个内部属性通......
  • 568. 蜡笔小新动漫主题 大学生期末大作业 Web前端网页制作 html+css+js
    目录一、网页概述二、网页文件三、网页效果四、代码展示1.html2.CSS3.JS五、总结1.简洁实用2.使用方便3.整体性好4.形象突出5.交互式强六、更多推荐欢迎光临仙女的网页世界!这里有各行各业的Web前端网页制作的案例,样式齐全新颖,并持续更新!感谢CSDN,提供了这......
  • 网关登录与web前端本地开发
    网关登录与web前端本地开发场景描述:管理后台和测试环境等服务部署在内网,访问这些资源需要网关验证访问权限;在线上访问这些资源时,会自动跳转要求网关登录,登录完成再重新跳回来。在本地开发时网关拒绝登录跳转。流程分析:在访问需要网关验证的资源时,请求会在cookie中携带权限tok......
  • 566. 火影忍者动漫主题网页 大学生期末大作业 Web前端网页制作 html+css
    目录一、网页概述二、网页文件 三、网页效果四、代码展示1.html2.CSS五、总结1.简洁实用2.使用方便3.整体性好4.形象突出5.交互式强六、更多推荐欢迎光临仙女的网页世界!这里有各行各业的Web前端网页制作的案例,样式齐全新颖,并持续更新!感谢CSDN,提供了这么好......