token登录的实现

token登录的实现

我这种token只是简单的实现token,就是后端利用UUID 生成简单随机码,利用随机码作为在Redis中的键,然后存储的用户信息作为值,在每次合理请求的时候对token的有效时间进行刷新(利用拦截器),以确保用户信息的有效性。

为什么要用token

使用令牌(Token)进行身份验证和授权是一种常见的方式,特别适用于分布式和跨域请求的应用程序。

1. 为什么要使用 Token:

  • 无状态性:Token 身份验证是无状态的,不需要在服务器端存储会话信息。每个请求都包含了身份信息,因此服务器不需要维护状态。
  • 跨域支持:Token 可以轻松处理跨域请求,因为令牌可以在 HTTP 请求的头部(通常是 Authorization 头部)中传递,而不受同源策略的限制。
  • 扩展性:Token 可以包含任意信息,因此可以用于传递用户权限、角色、过期时间等信息。

2. Token 使用逻辑:

  • 用户登录成功后,生成一个 Token 并将用户信息存储在服务器端(如 Redis)以便快速验证和获取用户信息。
  • 向前端返回 Token。
  • 前端将 Token 存储在本地(通常是 sessionStorage 或 localStorage)。
  • 在每个后续的请求中,前端将 Token 通过请求头(通常是 Authorization 头)发送给后端。
  • 后端从请求头中获取 Token,验证其合法性,并使用 Token 获取用户信息。

后端(Spring Boot)示例:

定义login接口

@GetMapping("/login")public BaseResponse<String> login(String username,String password){LambdaQueryWrapper<User> lambdaQueryWrapper = new LambdaQueryWrapper<>();lambdaQueryWrapper.eq(User::getUsername,username);User one = userService.getOne(lambdaQueryWrapper);if(one == null){throw new BusinessException(ErrorCode.NOT_FOUND_ERROR);}String token = UUID.randomUUID().toString();redisTemplate.opsForHash().putAll("test:user:"+token, BeanUtil.beanToMap(one));redisTemplate.expire("test:user:" + token,2, TimeUnit.MINUTES);return ResultUtils.success(token);}

定义一个获取用户信息的其他接口

@GetMapping("/get")public BaseResponse<User> get(){return ResultUtils.success(UserHolder.getValue());}

创建拦截器:

public class LoginInterceptor implements HandlerInterceptor {private RedisTemplate<String,Object> redisTemplate;public LoginInterceptor(RedisTemplate<String,Object> template){this.redisTemplate = template;}@Overridepublic boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)throws Exception {// 获取 sessionString token = request.getHeader("Authorization");// 检查用户是否已登录User user = new User();BeanUtil.fillBeanWithMap(redisTemplate.opsForHash().entries("test:user:"+token),user,false);if(user == null|| BeanUtil.isEmpty(user)){throw new BusinessException(ErrorCode.NOT_LOGIN_ERROR);}redisTemplate.expire("test:user:"+token,2, TimeUnit.MINUTES);// 将用户数据存储到 ThreadLocal 中,以便在整个请求周期内访问UserHolder.setValue(user);// 进行其他逻辑验证,根据需求自行添加return true; // 允许请求继续执行}@Overridepublic void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler,ModelAndView modelAndView) throws Exception {// 在请求处理之后执行,可以对 ModelAndView 进行修改}@Overridepublic void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex)throws Exception {// 在请求完成之后执行,用于资源清理等操作// 清理 ThreadLocal 中的用户数据,防止内存泄漏UserHolder.clear();}

注册拦截器:

@Configuration
public class MvcConfig implements WebMvcConfigurer {@Resourceprivate RedisTemplate<String,Object> redisTemplate;@Overridepublic void addInterceptors(InterceptorRegistry registry) {// 登录拦截器registry.addInterceptor(new LoginInterceptor(redisTemplate)).addPathPatterns("/**").excludePathPatterns("/user/login");}
}

使用结果截图

结果返回了一个token,这个token前端拿到以后要保存到sessionStorage或者LocalStorage里面,再把这个token送到请求头中,就可以啦

在这里插入图片描述

另一个请求:

设置请求头

设置Authorization
在这里插入图片描述
然后发起就可以得到啦
在这里插入图片描述

如果没有authorization就是得到未登录结果

在这里插入图片描述

前端(Vue.js)示例:

<!-- Login.vue -->
<template><div><input v-model="username" placeholder="Username" /><input type="password" v-model="password" placeholder="Password" /><button @click="login">Login</button></div>
</template><script>
export default {data() {return {username: '',password: ''};},methods: {login() {// 发送登录请求,获取 Tokenaxios.post('/api/user/login', { username: this.username, password: this.password }).then(response => {const token = response.data.token;// 存储 Token 到 sessionStoragesessionStorage.setItem('token', token);// 跳转到其他页面或进行其他操作}).catch(error => {console.error('Login failed:', error);});}}
};
</script>

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

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

相关文章

Android App ~ LiveData

LiveData 两种更新数据方式 setValue(T value)postValue(T value) setValue()只能在主线程中调用&#xff0c;postValue()可以在任何线程中调用。 MutableLiveData 1.首先LiveData其实与数据实体类(POJO类)是一样的东西,它负责暂存数据. 2.其次LiveData其实也是一个观察者…

FPGA project : DS18B20

本想着一天发一个实验的&#xff0c;这个ds18b20&#xff0c;耗时两天。代码写了两次&#xff0c;呜呜~ 由于第二次写代码没画时序图&#xff0c;所以代码和时序图一些参数有些不一致&#xff0c;但问题不大。 这里有几件事情值得一提&#xff1a; 1&#xff1a;关于状态机的…

ceph分布式存储

ceph特点 Ceph项目最早起源于Sage就读博士期间的工作&#xff08;最早的成果于2004年发表&#xff09;&#xff0c;并随后贡献给开源社区。在经过了数年的发展之后&#xff0c;目前已得到众多云计算厂商的支持并被广泛应用。RedHat及OpenStack都可与Ceph整合以支持虚拟机镜像的…

【C语言】求一个整数的二进制序列中1的个数的三种方法

方法一&#xff1a;逐位%2法 该方法的初步测试代码如下: int NumberOf1(int n) {int count 0;while (n){if (n % 2 1){count;}n n / 2;}return count; } 众所周知&#xff0c;数据在内存里以补码的形式存储&#xff0c;这是为了简化计算机的结构设计&#xff0c;同时也提…

MQ - 18 安全_身份认证、资源鉴权和加密传输的设计

文章目录 导图概述网络隔离的安全性数据传输过程加密SSL/TLS 区别联系连接建立时的身份认证框架和实现身份认证框架Kafka --- SASL是什么Pulsar & RabbitMQ身份认证实现用户名 + 密码的机制KerberosOAuth 认证集群资源的访问控制数据类和资源类操作控制两条链路单条链路访问…

【数据结构】哈希表(详)

文章目录 前言正文一、基本概念二、基本原理1.哈希函数1.1直接定址法&#xff08;常用&#xff09;1.2除留余数法&#xff08;常用&#xff09;1.3 平方取中法&#xff08;了解&#xff09;1.4 折叠法(了解)1.5 随机数法(了解)1.6数学分析法(了解) 2.哈希冲突2.1 平均查找长度2…

Python —— excel文件操作(超详细)

背景 很多公司还是用excel去管理测试用例的&#xff0c;所以为了减少重复繁琐的导出导出工作&#xff0c;学会如何用代码操作excel表格很实用~ 1、读取excel文件基本步骤 1、操作excel的一些库 1、xlrd&#xff1a;读取库&#xff0c;xlwt&#xff1a;写入&#xff0c;现在…

No servers available for service: renren…。 Gateway 网关报503错误 ,已解决

目录 环境配置问题描述loadbalancer的作用 环境配置 问题描述 配置spring cloud gateway使用端口访问就可以&#xff0c;使用lb:// 就报503 gateway:routes:- id: admin_routeuri: lb://gulimall-admin # uri: http://localhost:8080predicates:- Path/api/**filter…

JVM-环境准备性能指标基础知识

环境准备&性能指标&基础知识 环境准备 JDK — 工具 JDK&#xff08;Java Development Kit&#xff09; 是用于开发 Java 应用程序的软件开发工具集合&#xff0c;包括了 Java 运行时的环境&#xff08;JRE&#xff09;、解释器&#xff08;Java&#xff09;、编译器…

蓝桥杯 题库 简单 每日十题 day7

01 啤酒和饮料 题目描述 本题为填空题&#xff0c;只需要算出结果后&#xff0c;在代码中使用输出语句将所填结果输出即可。啤酒每罐2.3元&#xff0c;饮料每罐1.9元。小明买了若干啤酒和饮料&#xff0c;一共花了82.3元。我们还知道他买的啤酒比饮料的数量少&#xff0c;请你…

CVPR 2023 | UniMatch: 重新审视半监督语义分割中的强弱一致性

在这里和大家分享一下我们被CVPR 2023录用的工作"Revisiting Weak-to-Strong Consistency in Semi-Supervised Semantic Segmentation"。在本工作中&#xff0c;我们重新审视了半监督语义分割中的“强弱一致性”方法。我们首先发现&#xff0c;最基本的约束强弱一致性…

RHCE---时间服务器

文章目录 前言一、pandas是什么&#xff1f;二、使用步骤 1.引入库2.读入数据总结 前言 Linux中的时间服务器是指NTP服务器&#xff0c;NTP是Network Time Protocol的缩写&#xff0c;即网络时间协议。NTP服务器可以提供精确的时间信息&#xff0c;从而使得网络上的所有设备都能…

C语言文件的相关操作

C语言中文件的相关操作 文件的打开 使用文件的打开函数需要引入这个头文件&#xff1a;#include <fcntl.h> open函数 int open(char const *pathname, int flags, mode_t mode) 功能&#xff1a;打开已有的文件或者创建新文件参数 pathname&#xff1a;文件路径名&…

基于Python+Tkinter实现一个贪食蛇小游戏

你是否还记得那个时代&#xff0c;当我们的手机还没有触摸屏&#xff0c;游戏也只有像“贪食蛇”这样的经典款&#xff1f;当时&#xff0c;许多人都沉迷于控制一条小蛇吃食物的乐趣中。而今&#xff0c;让我们利用Python和Tkinter&#xff0c;一起重温那个时代&#xff0c;制作…

C语言基础知识点(八)联合体和大小端模式

以下程序的输出是&#xff08;&#xff09; union myun {struct { int x, y, z;} u;int k; } a; int main() {a.u.x 4;a.u.y 5;a.u.z 6;a.k 0;printf("%d\n", a.u.x); } 小端模式 数据的低位放在低地址空间&#xff0c;数据的高位放在高地址空间 简记&#xff…

使用Java将PPT、PPTX和PDF转换为图片

从Office到图片—使用Java实现文件格式转换 PDF转图片1. 万事第一步2. 撸代码 PPT/PPTX转图片1. 万事第一步2. 撸代码验收一下 最近小雨遇到了一个需求&#xff0c;需要在前端小程序中嵌入展示Office文件的功能。然而&#xff0c;前端使用开源组件进行在线预览会导致性能消耗较…

wpf制作自定义控件,并触发外部路由事件

目的是在前端增加一个自定义控件里的button后&#xff0c;按下动作可以调用使用该控件的页面的事件 首先在前端增加自定义控件里加入一个button&#xff0c;在其cs页面里注册点击事件 var btnAdd GetTemplateChild("btnAdd") as FlatButton;if (btnAdd ! null){btn…

R语言贝叶斯广义线性混合(多层次/水平/嵌套)模型GLMM、逻辑回归分析教育留级影响因素数据...

全文下载链接&#xff1a;http://tecdat.cn/?p24203 本教程使用R介绍了具有非信息先验的贝叶斯 GLM&#xff08;广义线性模型&#xff09; &#xff08;点击文末“阅读原文”获取完整代码数据&#xff09;。 当前教程特别关注贝叶斯逻辑回归在二元结果和计数/比例结果场景中的…

基于SSM框架的《超市订单管理系统》Web项目开发(第四天)用户管理,增删改查(日期插件的使用)

基于SSM框架的《超市订单管理系统》Web项目开发&#xff08;第四天&#xff09;用户管理&#xff0c;增删改查&#xff08;日期插件的使用&#xff09; 昨天我们实现了多表关联查询&#xff0c;还有分页显示数据的功能。那么今天我们要继续完善用户管理这一模块。 今天要完成的…

clickhouse简单安装部署

目录 前言(来源于官方文档)&#xff1a; 一.下载并上传 1.下载地址&#xff1a;点我跳转下载 2.上传至Linux 二.解压和配置 1.解压顺序 注意&#xff1a;必须按照以下顺序解压&#xff0c;并且每解压一个都要执行该解压后文件的install/doinst.sh文件 解压步骤&#xff…