Java实现登录验证 -- JWT令牌实现

news/2024/12/22 11:26:16/

目录

  • 1.实现登录验证的引出
    • 原因
  • 2.JWT令牌
    • 2.1 使用JWT令牌时
    • 2.2 令牌的组成
  • 3. JWT令牌(token)生成和校验
    • 3.1 引入JWT令牌的依赖
    • 3.2 使用Jar包中提供的API来实现JWT令牌的生成和校验
    • 3.3 使用JWT令牌验证登录
    • 3.4 令牌的优缺点

1.实现登录验证的引出

传统思路下:

  1. 登录页面把用户名和密码交给服务器。
  2. 服务器验证用户名和密码是否正确,并返回校验结果给后端。
  3. 如果密码正确,就会在服务器创建Session,通过Cookie把sessionId返回给客户端。

原因

但是在集群环境下,无法直接使用Session。因为如果只部署在一台机器时,容易发生单点故障(一旦这台服务器挂了,整个应用就无法访问),所以通常情况下,一个Web应用会部署在多个服务器上,通过Nginx等进行负载均衡。此时,来自一个用户的请求就会分发到不同的服务器上

在这里插入图片描述

  • 使用Session时:
    1. 用户登录: 用户登录请求,经过负载均衡发送给服务器1,服务器1进行用户名和密码验证,验证成功后,把Session存在了服务器1上。
    2. 查询操作:用户登录之后,携带Cookie(里面带有SessionId)继续执行查询操作,假如进行查询博客列表,此时请求经过负载均衡发到服务器2上,服务器2会先通过SessionId验证用户是否登录,此时第二台机器上没有该用户的Session,即出现查询不了的问题。

在这里插入图片描述

2.JWT令牌

JWT全称:JSON Web Token,用于客户端和服务器之间传递安全可靠的信息,本质是一个token,也叫token,令牌的本质就是一个字符串。相当于现在人们的身份证,出门在外验证身份的时候,拿出身份证即可。

2.1 使用JWT令牌时

  1. 用户登录 : 用户登录请求,经过负载均衡,把请求发给服务器1,服务器1进行账号密码验证,验证成功之后,生成一个令牌,并返回给客户端。
  2. 客户端收到令牌时,把令牌存储起来,可以存储在Cookie中,也可以存储在其它的存储空间,典型的如(localStorage)
  3. 查询操作 用户登录之后,携带令牌继续执行查询操作,假如查询博客列表,此时请求经过负载均衡发到服务器2,服务器2先进行权限验证操作。服务器验证令牌是否有效,如果有效,说明用户已经执行了登录操作,如果无效,说明用户之前未执行登录操作。

在这里插入图片描述

2.2 令牌的组成

令牌官网所示,token,本质上一个字符串中间使用 符号 点 . 来分割,令牌由三部分组成,header、payload和verify signature

在这里插入图片描述

  • 第一部分:Header(头),令牌的类型和使用的签名算法,如"alg": “HS256(哈希算法)”, “typ”: “JWT”。

  • 第二部分:Payload(负载),存放一些有效的信息(自定义信息,默认信息)如{“id”:“1”,“username”:“zhangsan”},还存在JWT提供的现场字段,如过期时间戳等。

  • 第三部分:Signature(签名),防止token被篡改,确保安全性

    签名的目的就是为了防止token被篡改,而正因为token最后一个部分签名存在,
    所以整个token是非常安全可靠的,一旦token当中的任何一部分被修改,
    整个token在校验的时候都会失败。 
    

3. JWT令牌(token)生成和校验

3.1 引入JWT令牌的依赖

  • 在pom.xml文件中引入依赖
java"><!-- https://mvnrepository.com/artifact/io.jsonwebtoken/jjwt-api --><dependency><groupId>io.jsonwebtoken</groupId><artifactId>jjwt-api</artifactId><version>0.11.5</version></dependency><!-- https://mvnrepository.com/artifact/io.jsonwebtoken/jjwt-impl --><dependency><groupId>io.jsonwebtoken</groupId><artifactId>jjwt-impl</artifactId><version>0.11.5</version><scope>runtime</scope></dependency><dependency><groupId>io.jsonwebtoken</groupId><artifactId>jjwt-jackson</artifactId> <!-- or jjwt-gson if Gson is
preferred --><version>0.11.5</version><scope>runtime</scope></dependency>

3.2 使用Jar包中提供的API来实现JWT令牌的生成和校验

  • 生成token之后,获取token进行解析,创建解释器,设置签名密钥,如果解析token的claims内容不为null,说明校验成功,否则失败。
java">package com.example.blog.utils;import com.example.blog.constant.Constants;
import io.jsonwebtoken.Claims;
import io.jsonwebtoken.JwtParser;
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.SignatureAlgorithm;
import io.jsonwebtoken.io.Decoders;
import io.jsonwebtoken.io.Encoders;
import io.jsonwebtoken.security.Keys;
import lombok.extern.slf4j.Slf4j;import javax.crypto.SecretKey;
import java.security.Key;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;@Slf4j
public class JwtUtils {// JWT过期时间public static final long JWT_EXPIRATION = 60*60*60*1000;// 生成keyprivate static final String secretStr = "DuJXRS2W3AJHqyFhAplBmsPNawnEdFYFNmlNdMbyU9w=";private static final Key key = Keys.hmacShaKeyFor(Decoders.BASE64.decode(secretStr));/***  生成token*/public static String genJwtToken(Map<String,Object> claim) {String token = Jwts.builder().setClaims(claim).setExpiration(new Date(System.currentTimeMillis()+JWT_EXPIRATION)).signWith(key).compact();return token;}/***  校验token*  Claims 为空,表示jwt校验失败**/public static Claims parseToken(String token) {// 创建解析器,设置签名密钥JwtParser build = Jwts.parserBuilder().setSigningKey(key).build();Claims claims = null;try {// 解析tokenclaims = build.parseClaimsJws(token).getBody();}catch (Exception e){log.error("解析token失败,token:{}",token);return null;}return claims;}
}

3.3 使用JWT令牌验证登录

在这里插入图片描述

3.4 令牌的优缺点

  1. 优点:
    • 解决了集群环境下认证的问题
    • 不需要在服务器端存储,从而减轻了服务器的存储压力
  2. 缺点:
    • 需要自己实现令牌的生成、传递、校验

http://www.ppmy.cn/news/1473668.html

相关文章

huggingface笔记:gpt2

0 使用的tips GPT-2是一个具有绝对位置嵌入的模型&#xff0c;因此通常建议在输入的右侧而不是左侧填充GPT-2是通过因果语言建模&#xff08;CLM&#xff09;目标进行训练的&#xff0c;因此在预测序列中的下一个标记方面非常强大 利用这一特性&#xff0c;GPT-2可以生成语法连…

VitePress美化

参考资料&#xff1a; https://blog.csdn.net/weixin_44803753/article/details/130903396 https://blog.csdn.net/qq_30678861/category_12467776.html 站点信息修改 首页部分的修改基本都在.vitepress/config.mts,这个文件内修改。 title 站点名称 description 描述 top…

【Git 学习笔记】第二章 Git 的配置(下)

2.5 几个配置示例 2.5.1 变基&#xff08;rebase&#xff09;与合并&#xff08;merge&#xff09;设置 默认情况下&#xff0c;在执行 git pull 时&#xff0c;如果本地分支的历史记录与远程分支的历史不同&#xff0c;则会进行合并提交。修改默认方式可使用&#xff1a; #…

Pytorch中方法对象和属性,例如size()和shape

文章目录 方法对象和属性的基本概念方法对象属性示例说明总结 常见的方法对象和属性常见的方法对象常见的属性总结示例 方法对象和属性的基本概念 方法对象&#xff08;method object&#xff09;和属性&#xff08;attribute&#xff09;是面向对象编程中的两个重要概念。让我…

使用Python绘制堆积柱形图

使用Python绘制堆积柱形图 堆积柱形图效果代码 堆积柱形图 堆积柱形图&#xff08;Stacked Bar Chart&#xff09;是一种数据可视化图表&#xff0c;用于显示不同类别的数值在某一变量上的累积情况。每一个柱状条显示多个子类别的数值&#xff0c;子类别的数值在柱状条上堆积在…

【IT领域新生必看】 Java编程中的重载(Overloading):初学者轻松掌握的全方位指南

文章目录 引言什么是方法重载&#xff08;Overloading&#xff09;&#xff1f;方法重载的基本示例 方法重载的规则1. 参数列表必须不同示例&#xff1a; 2. 返回类型可以相同也可以不同示例&#xff1a; 3. 访问修饰符可以相同也可以不同示例&#xff1a; 4. 可以抛出不同的异…

cs224n作业4

NMT结构图&#xff1a;&#xff08;具体结构图&#xff09; LSTM基础知识 nmt_model.py&#xff1a; 参考文章&#xff1a;LSTM输出结构描述 #!/usr/bin/env python3 # -*- coding: utf-8 -*-""" CS224N 2020-21: Homework 4 nmt_model.py: NMT Model Penchen…