首页 > 编程语言 >Java实现登录验证 -- JWT令牌实现

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

时间:2024-07-02 16:58:17浏览次数:14  
标签:令牌 Java -- JWT token io 服务器 import

目录

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在校验的时候都会失败。 
    

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

3.1 引入JWT令牌的依赖

  • 在pom.xml文件中引入依赖
<!-- 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,说明校验成功,否则失败。
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;
    // 生成key
    private 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 {
            // 解析token
            claims = build.parseClaimsJws(token).getBody();
        }catch (Exception e){
            log.error("解析token失败,token:{}",token);
            return null;
        }
        return claims;
    }
}

3.3 使用JWT令牌验证登录

在这里插入图片描述

标签:令牌,Java,--,JWT,token,io,服务器,import
From: https://blog.csdn.net/m0_63440113/article/details/140127885

相关文章

  • 网络安全(黑客)自学
    当我们谈论网络安全时,我们正在讨论的是保护我们的在线空间,这是我们所有人的共享责任。网络安全涉及保护我们的信息,防止被未经授权的人访问、披露、破坏或修改。一、网络安全的基本概念网络安全是一种保护:它涉及保护我们的设备和信息,从各种威胁,如病毒和蠕虫,到更复杂的形式的网......
  • Openssh版本过低被扫出漏洞---Openssh修改版本号
    1.查看当前系统的ssh版本号ssh-Vsshd-V2.查看ssh和sshd的位置whichsshwhichsshd3.查看ssh版本号有关的字符串strings/usr/bin/ssh|grepOpenSSHstrings/usr/sbin/sshd|grepOpenSSH4.备份cp/usr/bin/ssh/usr/bin/ssh.bakcp/usr/sbin/ss......
  • 字典的增删改查
      #字典是根据键查询的,并且是无序的,键是唯一的并且不能修改dict_product={"电视":1300,"冰箱":1500,"空调":2000,"电脑":5000}#查print(dict_product["冰箱"])#查询键为冰箱的值num=dict_product.get("空调")#查询键对应的值print(num)......
  • 基于51单片机的光照强度检测系统设计与实现
    基于51单片机的光照强度检测系统设计与实现摘要本文设计并实现了一个基于51单片机的光照强度检测系统,该系统利用光敏电阻作为光照强度检测元件,通过ADC转换器将模拟信号转换为数字信号,并由51单片机进行处理和显示。系统具备实时检测、数据转换、存储及显示功能,适用于各种需要......
  • Python对历年高考分数线数据用聚类、决策树可视化分析一批、二批高校专业、位次、计划
    全文链接:https://tecdat.cn/?p=36626原文出处:拓端数据部落公众号随着高等教育的普及与竞争的日益激烈,高考作为通往高等教育的重要门槛,其分数线的波动、高校及专业的选择成为了社会广泛关注的焦点。考生和家长在面临众多高校和专业的选择时,往往需要综合考虑多种因素,如分数线、专......
  • 阿里228x82y还原之递归数组解密
    声明本文章中所有内容仅供学习交流,抓包内容、敏感网址、数据接口均已做脱敏处理,严禁用于商业用途和非法用途,否则由此产生的一切后果均与作者无关,若有侵权,请联系我立即删除!目标网站某里228分析逆向流程228递归函数str解密原理就是用数组push最后填充下,然后解密出来多了......
  • C#基础2024.07.02
    目录1.变量的作用域有哪些?2.成员变量和静态变量的区别?成员变量(实例变量)静态变量(类变量)3.利用递归,写个文件目录遍历,打印出文件名、扩展名、文件大小4.简述访问修饰符有几种,各有什么不同?(1)public(2)private(3)protected(5)internal(6)protectedinternal5.重点比较public、pr......
  • ffmpeg在Windows上的安装
    首先进入官网DownloadFFmpeg选择windows版本下载想要的版本Gyan.dev的版本可能会更符合Windows标准,而BtbN的版本可能会更加开放和跨平台往下拉选择想要的版本进行下载我下载的是第一个下载好之后解压文件复制bin目录的路径 接着按照下面的顺序进行环境配置,结束后一路确......
  • wpf关于Resource,Style的定义与引用,滑动按钮
    当我们使用wpf框架去搭建自己的程序时,一般都会重写wpf原生的一些样式,以达到软件风格的统一于美化,以下介绍一下常见的几种添加Style的方式我们以一个滑动按钮为例1.对当前控件的样式进行更改<ToggleButton><ToggleButton.Style><StyleTarg......
  • ELF 文件与链接
    ELF文件与链接Created:2024-07-02T11:03+08:00Published:2024-07-02T16:44+08:00Categories:OperatingSystem目录工具:readelf和objdump程序=指令+数据符号表静态链接与重定位不知道的地址先用0填充重定位表记录那些暂时用0填充的位置链接后修改位置*.o没有seg......