使用 Sa-Token 实现 [记住我] 模式登录、七天免登录

news2024/11/18 8:19:56

一、需求分析

如图所示,一般网站的登录界面都会有一个 [记住我] 按钮,当你勾选它登录后,即使你关闭浏览器再次打开网站,也依然会处于登录状态,无须重复验证密码:

../static/login-view.png

本文将详细介绍在 Sa-Token中,如何做到以下登录模式:

  • 记住我登录:登录后关闭浏览器,再次打开网站登录状态依然有效,无需重复登录。
  • 仅本次有效登录:登录后关闭浏览器,再次打开网站登录状态将失效,需要再次登录。
  • 七天免登录:为登录状态设定一个详细的有效期,在这个期限内无需重复登录,过了期限后需要再次登录。

Sa-Token 是一个轻量级 java 权限认证框架,主要解决登录认证、权限认证、单点登录、OAuth2、微服务网关鉴权 等一系列权限相关问题。

Gitee 开源地址:https://gitee.com/dromara/sa-token

首先在项目中引入 Sa-Token 依赖:

<!-- Sa-Token 权限认证 -->
<dependency>
    <groupId>cn.dev33</groupId>
    <artifactId>sa-token-spring-boot-starter</artifactId>
    <version>1.34.0</version>
</dependency>

注:如果你使用的是 SpringBoot 3.x,只需要将 sa-token-spring-boot-starter 修改为 sa-token-spring-boot3-starter 即可。

二、在 Sa-Token 中实现记住我功能

Sa-Token的登录授权,默认就是[记住我]模式,为了实现[非记住我]模式,你需要在登录时如下设置:

// 设置登录账号id为10001,第二个参数指定是否为[记住我],当此值为false后,关闭浏览器后再次打开需要重新登录
StpUtil.login(10001, false);

那么,Sa-Token实现[记住我]的具体原理是?

三、实现原理

Cookie作为浏览器提供的默认会话跟踪机制,其生命周期有两种形式,分别是:

  • 临时Cookie:有效期为本次会话,只要关闭浏览器窗口,Cookie就会消失。
  • 持久Cookie:有效期为一个具体的时间,在时间未到期之前,即使用户关闭了浏览器Cookie也不会消失。

利用Cookie的此特性,我们便可以轻松实现 [记住我] 模式:

  • 勾选 [记住我] 按钮时:调用StpUtil.login(10001, true),在浏览器写入一个持久Cookie储存 Token,此时用户即使重启浏览器 Token 依然有效。
  • 不勾选 [记住我] 按钮时:调用StpUtil.login(10001, false),在浏览器写入一个临时Cookie储存 Token,此时用户在重启浏览器后 Token 便会消失,导致会话失效。

动态演示图:

记住我登录

四、前后端分离模式下如何实现[记住我]?

此时机智的你😏很快发现一个问题,Cookie虽好,却无法在前后端分离环境下使用,那是不是代表上述方案在APP、小程序等环境中无效?

准确的讲,答案是肯定的,任何基于Cookie的认证方案在前后端分离环境下都会失效(原因在于这些客户端默认没有实现Cookie功能),不过好在,这些客户端一般都提供了替代方案,
唯一遗憾的是,此场景中token的生命周期需要我们在前端手动控制:

以经典跨端框架 uni-app 为例,我们可以使用如下方式达到同样的效果:

// 使用本地存储保存token,达到 [持久Cookie] 的效果
uni.setStorageSync("satoken", "xxxx-xxxx-xxxx-xxxx-xxx");

// 使用globalData保存token,达到 [临时Cookie] 的效果
getApp().globalData.satoken = "xxxx-xxxx-xxxx-xxxx-xxx";

如果你决定在PC浏览器环境下进行前后端分离模式开发,那么更加简单:

// 使用 localStorage 保存token,达到 [持久Cookie] 的效果
localStorage.setItem("satoken", "xxxx-xxxx-xxxx-xxxx-xxx");

// 使用 sessionStorage 保存token,达到 [临时Cookie] 的效果
sessionStorage.setItem("satoken", "xxxx-xxxx-xxxx-xxxx-xxx");

Remember me, it’s too easy!

五、登录时指定 Token 有效期

登录时不仅可以指定是否为[记住我]模式,还可以指定一个特定的时间作为 Token 有效时长,如下示例:

// 示例1:
// 指定token有效期(单位: 秒),如下所示token七天有效
StpUtil.login(10001, new SaLoginModel().setTimeout(60 * 60 * 24 * 7));

// ----------------------- 示例2:所有参数
// `SaLoginModel`为登录参数Model,其有诸多参数决定登录时的各种逻辑,例如:
StpUtil.login(10001, new SaLoginModel()
			.setDevice("PC")                 // 此次登录的客户端设备类型, 用于[同端互斥登录]时指定此次登录的设备类型
			.setIsLastingCookie(true)        // 是否为持久Cookie(临时Cookie在浏览器关闭时会自动删除,持久Cookie在重新打开后依然存在)
			.setTimeout(60 * 60 * 24 * 7)    // 指定此次登录token的有效期, 单位:秒 (如未指定,自动取全局配置的 timeout 值)
			.setToken("xxxx-xxxx-xxxx-xxxx") // 预定此次登录的生成的Token 
			.setIsWriteHeader(false)         // 是否在登录后将 Token 写入到响应头
			);

注:如果在登录时未指定 new SaLoginModel().setTimeout(604800) 那么框架将采用全局配置的 sa-token.timeout 值作为 Token 的有效期。

六、不同登录策略的代码对比

以下是三种登录策略的代码差异:

package com.pj.cases.up;

import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import cn.dev33.satoken.stp.StpUtil;
import cn.dev33.satoken.util.SaResult;

/**
 * Sa-Token 记住我模式登录 
 * 
 * @author kong
 * @since 2022-10-17 
 */
@RestController
@RequestMapping("/RememberMe/")
public class RememberMeController {

	// 记住我登录    ---- http://localhost:8081/RememberMe/doLogin?name=zhang&pwd=123456
	@RequestMapping("doLogin")
	public SaResult doLogin(String name, String pwd) {
		if("zhang".equals(name) && "123456".equals(pwd)) {
			StpUtil.login(10001, true);
			return SaResult.ok("登录成功");
		}
		return SaResult.error("登录失败");
	}
	
	// 不记住我登录    ---- http://localhost:8081/RememberMe/doLogin2?name=zhang&pwd=123456
	@RequestMapping("doLogin2")
	public SaResult doLogin2(String name, String pwd) {
		if("zhang".equals(name) && "123456".equals(pwd)) {
			StpUtil.login(10001, false);
			return SaResult.ok("登录成功");
		}
		return SaResult.error("登录失败");
	}

	// 七天免登录    ---- http://localhost:8081/RememberMe/doLogin3?name=zhang&pwd=123456
	@RequestMapping("doLogin3")
	public SaResult doLogin3(String name, String pwd) {
		if("zhang".equals(name) && "123456".equals(pwd)) {
			StpUtil.login(10001, 60 * 60 * 24 * 7);
			return SaResult.ok("登录成功");
		}
		return SaResult.error("登录失败");
	}
	
}

可依次访问注释中提供的测试链接,观察不同登录策略带来的会话有效期差异。


参考资料

  • Sa-Token 文档:https://sa-token.cc
  • Gitee 仓库地址:https://gitee.com/dromara/sa-token
  • GitHub 仓库地址:https://github.com/dromara/sa-token

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/660889.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

移动机器人底盘-四轮差速模型(四轮独立)

移动机器人底盘-四轮差速模型 文章目录 移动机器人底盘-四轮差速模型1. 四轮差速模型原理2. 工程实践2.1 Python实现2.2 C实现 1. 四轮差速模型原理 四轮差速模型底盘实例如下图所示。对于底盘的前轮和后轮来说&#xff0c;其速度是同步的&#xff0c;那么在理想条件下&#x…

PHY芯片的使用(一)之基本概念讲解(MII相关)2

今天想和大家交流一下MAC和PHY之间的接口MII。 MII(Media Independent Interface )是介质无关接口。MII接口定义了在MAC层和物理层之间传送数据和控制状态等信息的接口&#xff0c;它是10M和100M兼容的接口&#xff0c;经过扩展后还可以用于1000M的MAC层与物理层的接口&#x…

【libdatachannel】Transport的设计实现

作为ice传输实现的基类 具有实际的作用。 D:\XTRANS\thunderbolt\ayame\ZHB_LIB_DATACHANNEL\src\impl\transport.cpp 最重要的是封装了对impl的调用 Transport 比较牛,抽象了传输的基础能力 发送(调用ice接口发送) send(message_ptr message);接收(通过ice收到后使用回调方…

msvcp140.dll下载,无法启动此程序,因为计算机中丢失msvcp140.dll的解决方法

msvcp140.dll是动态链接库文件&#xff0c;是一种不可执行的二进制程序文件&#xff0c;允许程序共享执行特殊任务所需要的代码和其他资源。程序可根据DLL文件中的指令打开、启用、查询、禁用和关闭驱动程序。 很多小伙伴在使用电脑软件的时候&#xff0c;有一些问题会搞不明白…

layui框架学习(27:弹出层模块_其它用法)

除了前几篇文章介绍的弹出框类型外&#xff0c;layui的layer弹出层模块还支持相册框和tab框&#xff0c;所谓相册框即点击图片或按钮后会出现一个类似相册的页面单独浏览、切换图片&#xff0c;而tab框是指弹出框的显示形式类似于Winform中的TabControl控件&#xff0c;能以选项…

如何把一个 Git 仓库的分支加入另一个无关的 Git 仓库

文章目录 笔者需要将两个无关的 Git 仓库合并&#xff0c;也就是把一个 Git 仓库的分支加入另一个无关的 Git 仓库。笔者琢磨了一下之后就实现了。方法如下。 笔者的运行环境&#xff1a; git version 2.37.0.windows.1 TortoiseGit 2.11.0.0 IntelliJ IDEA 2023.1.1 (Ultima…

vue2_markdown的内容目录生成

文章目录 ⭐前言⭐引入vue-markdown&#x1f496; 全局配置&#x1f496; 渲染选项&#x1f496; 取出markdown的标题层级 ⭐结束 ⭐前言 大家好&#xff01;我是yma16&#xff0c;本文分享在vue2的markdown文本内容渲染和目录生成 背景&#xff1a; 优化个人博客功能&#xf…

Spring MVC简介附入门案例

目录 一、SpringMVC简介 1.1 MVC模型 1.2 SpringMVC 二、SpringMVC入门案例 2.1 创建项目 2.2 引入依赖和tomcat插件 2.3 修改web.xml文件 2.4 新建springmvc.xml文件 2.5 编写控制器 2.6 配置运行方式 2.7 运行测试 三、SpringMVC执行流程 3.1 SpringMVC的组件…

【FreeRTOS】FreeRTOS动态创建任务与删除

0. 实验准备 正点原子 STM32407ZG 探索者开发板 FreeRTOS 例程模板&#xff08;可以在这一篇文章找到&#xff1a;STM32F407 移植 FreeRTOS&#xff09; 1. 动态创建任务函数 API 1.1 函数简介 动态创建任务需要使用到BaseType_t xTaskCreate函数&#xff0c;我们可以在 Fr…

unittest教程__TestSuite测试套件(2)

在前面一章中演示了unittest如何执行一个简单的测试&#xff0c;但有两个问题&#xff1a; 我们知道测试用例的执行顺序是根据测试用例名称顺序执行的&#xff0c;在不改变用例名称的情况下&#xff0c;我们怎么来控制用例执行的顺序呢&#xff1f;一个测试文件&#xff0c;我…

事务底层与高可用原理

一、redo日志 在事务的实现机制上&#xff0c;MySQL采用的是WAL&#xff08;Write-ahead logging&#xff0c;预写式日志&#xff09;机制来实现的。 就是所有的修改都先被写入到日志中&#xff0c;然后再被应用到系统中。通常包含redo和undo两部分信息。 redo log称为重做日…

Spring执行流程和Bean的生命周期

1、Spring执行流程2、Bean的生命周期&#xff08;重点&#xff09;2.1、实例化和初始化的区别2.2、为什么先设置属性再进行初始化呢&#xff1f; 1、Spring执行流程 Spring执行流程&#xff08;Bean执行流程&#xff09;&#xff1a;1、在启动类中遇到了ApplicationContext的时…

【微服务】在window下安装nacos以及可能遇到的问题

介绍 这里是小编成长之路的历程&#xff0c;也是小编的学习之路。希望和各位大佬们一起成长&#xff01; 以下为小编最喜欢的两句话&#xff1a; 要有最朴素的生活和最遥远的梦想&#xff0c;即使明天天寒地冻&#xff0c;山高水远&#xff0c;路远马亡。 一个人为什么要努力&a…

【029】C++静态成员和 this 指针详解

C静态成员和 this 指针详解 引言一、静态成员1.1、静态成员变量1.2、静态成员变量的使用示例1.3、静态成员函数1.4、单例模式设计 二、C面向对象模型2.1、成员变量和函数的存储2.2、this 指针2.3、this 指针的应用2.4、const修饰成员函数 总结 引言 &#x1f4a1; 作者简介&…

.NET6创建Windows服务

之前的文章已经写过了创建Windows服务。 C#创建Windows服务_c# 创建windows服务_故里2130的博客-CSDN博客 不过之前使用的是.NET Framework创建的Windows服务。现在已经2023年了&#xff0c;其中vs2022有新的方法去创建Windows服务&#xff0c;本次使用.NET6创建Windows服务。…

网络层:虚拟专用网VPN和网络地址转换NAT

1.网络层&#xff1a;虚拟专用网VPN和网络地址转换NAT 笔记来源&#xff1a; 湖科大教书匠&#xff1a;虚拟专用网VPN和网络地址转换NAT 声明&#xff1a;该学习笔记来自湖科大教书匠&#xff0c;笔记仅做学习参考 1.1 虚拟专用网VPN 专用网和公用网的特点 专用网络&#xff…

远程访问VPN配置与验证实验:构建安全的远程连接

远程访问VPN配置与验证实验&#xff1a;构建安全的远程连接 【实验目的】 理解远程访问 VPN的含义。掌握远程访问 VPN的含义。掌握VPN Client软件的使用。验证配置。 【实验拓扑】 实验拓扑如下图所示。 实验拓扑 设备参数表如下表所示。 设备参数表 设备 接口 IP地址 …

【软件设计】模块设计耦合的七种类型

一.什么是高内聚、低耦合&#xff1f; 在结构化分析与模块设计方法中&#xff0c;模块化是一个很重要的概念&#xff0c;它是将一个待开发的软件分解成为若干个小的模块&#xff0c;每个模块可以独立地开发、测试。使得复杂问题的“分而治之”&#xff0c;令程序的结构清晰、易…

ubuntu 20.04 linux6.3.8 qemu arm64 平台 制作ext4根文件系统

前言 可以参考 ubuntu 20.04 qemu linux6.0.1 制作ext4根文件系统 因为需要验证 aarch64 平台下的 glib 库&#xff0c;所以重新搭建了 Linux qemu arm64 的 测试环境 这一篇&#xff0c;开始制作 rootfs 根文件系统&#xff0c;让qemu arm64 平台上的 Linux 系统跑起来 开…

一个springboot项目的jenkins持续集成配置

目录 1.项目基本情况 2.jenkins的下载 1) 安装jdk 2&#xff09;下载、启动和配置jenkins 3. 启动Jenkins 4. 安装Jenkins插件 5. 重启jenkins 6.jenkins工具的配置 1&#xff09; jdk的路径配置 7.创建springboot项目的持续集成任务 1) 新建项目 2&#xff09;代…