基于token进行登录,每次请求携带token

2024-04-26 09:28

本文主要是介绍基于token进行登录,每次请求携带token,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

一,什么是token?

Token,也称为“令牌”,是服务端生成的一串字符串,以作客户端进行请求的一个令牌,当第一次登录后,服务器生成一个Token便将此Token返回给客户端,以后客户端只需带上这个Token前来请求数据即可,无需再次带上用户名和密码。比如如下形式:eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJhdWQiOiJEenUyMDIwMDEwMTEwMzEiLCJleHAiOjE3MTQwNTM2MDV9.VBIWPBzGJRhwCB_jhI-wjZF8ErEFfpQkZOUmFxYQs5k

二、为什么使用Token

传统验证用户身份的方式,大多为基于服务器验证的方式,即cookie+session的方式,由于HTTP协议是无状态的,导致程序需要验证每一次请求,从而辨别客户端的身份。

用户登录成功将其信息存入session中,用户每次请求都会将携带session id的cookie一起发送器服务端,进行校验,随着Web、应用程序、以及移动端的崛起,这种验证方式弊端逐渐显现,尤其是在可扩展性方面。

引发的问题比如用户增多导致内存开销较大、CORS(跨域资源共享)以及CSRF(跨站请求伪造)等。

引入Token验证机制后,请求会发送token而不再是发送cookie能有效够防止CSRF,即使在客户端使用cookie存储token,但cookie也只有存储功能,而不再具备验证功能,因此安全性得到了极大的提高。

而且只要token设计的足够复杂,除非用户泄露,否则几乎没有被破解的可能,加上token是有时效的,在有限的时间加上有限的算力,更是无懈可击,这也类似于加密资产比如比特币钱包对应的私钥,安全性极高。

另外Token可以有效减轻服务器的压力,减少频繁的查询数据库,使服务器更加健壮。

三、Token的使用

什么是jwt?

JWT(JSON WEB TOKEN):JSON网络令牌,JWT是一个轻便的安全跨平台传输格式,定义了一个紧凑的自包含的方式在不同实体之间安全传输信息(JSON格式)。它是在Web环境下两个实体之间传输数据的一项标准。实际上传输的就是一个字符串。广义上讲JWT是一个标准的名称;狭义上JWT指的就是用来传递的那个token字符串。

前端axios请求拦截器

service.interceptors.request.use(config => {if (localStorage.getItem('token') !== null && localStorage.getItem('token') !== "" && localStorage.getItem('token') !== undefined) {config.headers['Authorization'] = 'Bearer ' + localStorage.getItem('token'); // 假设你存储token在localStorage中config.headers['Content-Type'] = 'application/json;charset=UTF-8'config.headers['Accept'] = 'application/json'config.headers['Access-Control-Allow-Origin'] = '*'} else {//跳转登录router.push({path: '/login'})}return config
}, error => {return Promise.reject(error)
})

spring boot使用jwt

 <dependency><groupId>com.auth0</groupId><artifactId>java-jwt</artifactId><version>4.3.0</version>
</dependency>

utils

package com.dzu.utils;import cn.hutool.core.date.DateUtil;
import com.auth0.jwt.JWT;
import com.auth0.jwt.JWTVerifier;
import com.auth0.jwt.algorithms.Algorithm;
import com.auth0.jwt.interfaces.DecodedJWT;
import com.dzu.domain.User;import java.util.Date;
import java.util.List;public class JwtTokenUtils {private static final String SECRET = "dzuojsystem"; // 你的密钥,应该保密public static String createToken(User user) {//将用户名放进去作为载荷进行加密return JWT.create().withAudience(user.getUsername())//传入当前时间对象,并指定两小时后token过期//也可以指定时分秒天,比如offsetMinute就表示指定有效期为30分钟.withExpiresAt(DateUtil.offsetMinute(new Date(), 30))//使用密钥作为token的密钥.sign(Algorithm.HMAC256(SECRET));}public String parseTokenUsername(String token) {try {//验证tokenreturn JWT.decode(token).getAudience().get(0);} catch (Exception e) {//有异常就是验证不通过了throw new RuntimeException("token验证失败");}}//判断token是否有效且合法public boolean validateToken(String token) {// 创建token验证器Algorithm algorithm = Algorithm.HMAC256(SECRET);JWTVerifier verifier = JWT.require(algorithm).withIssuer("dzuojsystem").build();// 验证tokentry {DecodedJWT jwt = verifier.verify(token);return true;} catch (Exception e) {return false;}}
}

配置拦截器 (可以自定义异常抛出)

//省略导包,自行导入//这是拦截器的具体的方法
@Controller
@CrossOrigin
public class ProjectInterceptor implements HandlerInterceptor {private static final String SECRET = "dzuojsystem"; // 你的密钥,应该保密@Resourceprivate UserMapper userMapper;public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {//首先要确定访问的是一个方法if (!(handler instanceof HandlerMethod)) {//这里表示当访问的是一个html页面的时候就直接结束,当访问的是一个方法的时候才会继续向下运行//比如拦截"/**"请求,然后访问/aa.html此时就会直接结束,但是访问的是/aa这个方法的话,就会打印"开始拦截"return true;}//然后判断请求中是否有token//从请求头中获取tokenString token = request.getHeader("Authorization").substring(7);System.out.println("authorization----token:"+token);//主要用来判断字符串类型的变量是否为空if (StrUtil.isBlank(token) || token == null) {throw new Exception("无token,请重新登陆");}//然后解析token中的载荷,但这一步无法判断token是否过期String Username;try {//解析token中的主体中的数据,结果为[username],就是之前加密的数据List<String> ff = JWT.decode(token).getAudience();//解析token从中获取载荷中的第一个数据,如果这串代码运行异常则说明该token字符串有问题Username = ff.get(0);} catch (Exception e) {//此时说明token字符串已经被串改,导致解析失败throw new Exception("token验证失败,请重新登陆");}//通过用户名查询信息User user = userMapper.selectOne(new QueryWrapper<User>().eq("username", Username));if (user == null) {throw new Exception("用户不存在,该token不合法");}//验证token//通过添加密钥来创建验证对象,从而验证token是否过期,因为即使过期了,上面也能解析到数据JWTVerifier jwtVerifier = JWT.require(Algorithm.HMAC256(SECRET)).build();try {jwtVerifier.verify(token);} catch (JWTVerificationException e) {throw new Exception("token验证失败,请重新登陆");}return true;}public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {}public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {}
}

@Controller
public class SpringMvcSupport implements WebMvcConfigurer {@Resourceprivate ProjectInterceptor projectInterceptor;public void addInterceptors(InterceptorRegistry registry) {//这里是注册拦截器registry.addInterceptor(projectInterceptor).addPathPatterns("/**")//放行接口,自己决定放行那些接口.excludePathPatterns("/user/register").excludePathPatterns("/user/login").excludePathPatterns("/email/sendMail").excludePathPatterns("/jwt/validateToken");}
}

记得前端登录的时候,要把生成的token存起来,例如localstorage里面。

大致的流程

后端生成token--->前端保存token------>通过前端的拦截器给请求头添加token----->后端通过拦截器验证token。

大致就是这样,可能会有错误,请包涵!

这篇关于基于token进行登录,每次请求携带token的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/937206

相关文章

Linux使用fdisk进行磁盘的相关操作

《Linux使用fdisk进行磁盘的相关操作》fdisk命令是Linux中用于管理磁盘分区的强大文本实用程序,这篇文章主要为大家详细介绍了如何使用fdisk进行磁盘的相关操作,需要的可以了解下... 目录简介基本语法示例用法列出所有分区查看指定磁盘的区分管理指定的磁盘进入交互式模式创建一个新的分区删除一个存

C#使用HttpClient进行Post请求出现超时问题的解决及优化

《C#使用HttpClient进行Post请求出现超时问题的解决及优化》最近我的控制台程序发现有时候总是出现请求超时等问题,通常好几分钟最多只有3-4个请求,在使用apipost发现并发10个5分钟也... 目录优化结论单例HttpClient连接池耗尽和并发并发异步最终优化后优化结论我直接上优化结论吧,

使用Python进行文件读写操作的基本方法

《使用Python进行文件读写操作的基本方法》今天的内容来介绍Python中进行文件读写操作的方法,这在学习Python时是必不可少的技术点,希望可以帮助到正在学习python的小伙伴,以下是Pyth... 目录一、文件读取:二、文件写入:三、文件追加:四、文件读写的二进制模式:五、使用 json 模块读写

Java后端接口中提取请求头中的Cookie和Token的方法

《Java后端接口中提取请求头中的Cookie和Token的方法》在现代Web开发中,HTTP请求头(Header)是客户端与服务器之间传递信息的重要方式之一,本文将详细介绍如何在Java后端(以Sp... 目录引言1. 背景1.1 什么是 HTTP 请求头?1.2 为什么需要提取请求头?2. 使用 Spr

使用zabbix进行监控网络设备流量

《使用zabbix进行监控网络设备流量》这篇文章主要为大家详细介绍了如何使用zabbix进行监控网络设备流量,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编一起学习一下... 目录安装zabbix配置ENSP环境配置zabbix实行监控交换机测试一台liunx服务器,这里使用的为Ubuntu22.04(

在Pandas中进行数据重命名的方法示例

《在Pandas中进行数据重命名的方法示例》Pandas作为Python中最流行的数据处理库,提供了强大的数据操作功能,其中数据重命名是常见且基础的操作之一,本文将通过简洁明了的讲解和丰富的代码示例,... 目录一、引言二、Pandas rename方法简介三、列名重命名3.1 使用字典进行列名重命名3.编

python安装完成后可以进行的后续步骤和注意事项小结

《python安装完成后可以进行的后续步骤和注意事项小结》本文详细介绍了安装Python3后的后续步骤,包括验证安装、配置环境、安装包、创建和运行脚本,以及使用虚拟环境,还强调了注意事项,如系统更新、... 目录验证安装配置环境(可选)安装python包创建和运行Python脚本虚拟环境(可选)注意事项安装

如何使用celery进行异步处理和定时任务(django)

《如何使用celery进行异步处理和定时任务(django)》文章介绍了Celery的基本概念、安装方法、如何使用Celery进行异步任务处理以及如何设置定时任务,通过Celery,可以在Web应用中... 目录一、celery的作用二、安装celery三、使用celery 异步执行任务四、使用celery

python实现自动登录12306自动抢票功能

《python实现自动登录12306自动抢票功能》随着互联网技术的发展,越来越多的人选择通过网络平台购票,特别是在中国,12306作为官方火车票预订平台,承担了巨大的访问量,对于热门线路或者节假日出行... 目录一、遇到的问题?二、改进三、进阶–展望总结一、遇到的问题?1.url-正确的表头:就是首先ur

SpringBoot项目引入token设置方式

《SpringBoot项目引入token设置方式》本文详细介绍了JWT(JSONWebToken)的基本概念、结构、应用场景以及工作原理,通过动手实践,展示了如何在SpringBoot项目中实现JWT... 目录一. 先了解熟悉JWT(jsON Web Token)1. JSON Web Token是什么鬼