Java實現登錄驗證 -- JWT令牌實現

目錄

  • 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文件中引入依賴
<!-- 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;// 生成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.pswp.cn/web/40910.shtml
繁體地址,請注明出處:http://hk.pswp.cn/web/40910.shtml
英文地址,請注明出處:http://en.pswp.cn/web/40910.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

強化Linux系統安全性:從基礎命令到高級管理

強化Linux系統安全性&#xff1a;從基礎命令到高級管理 引言 在網絡安全領域&#xff0c;Linux系統因其穩定性和安全性而廣受歡迎。作為一名網絡安全專家&#xff0c;我將分享如何通過Linux基礎命令和高級管理技巧來加強系統的安全性。本文將基于《學神 IT 教育》提供的Linux…

Debezium報錯處理系列之第110篇: ERROR Error during binlog processing.Access denied

Debezium報錯處理系列之第110篇:ERROR Error during binlog processing. Last offset stored = null, binlog reader near position = /4 Access denied; you need at least one of the REPLICATION SLAVE privilege for this operation 一、完整報錯二、錯誤原因三、解決方法…

python 切入點(EntryPoints)使用

文章目錄 EntryPoints 介紹EntryPoints案例EntryPoints 介紹 官網參考 EntryPoints 是發布的python 項目的一種機制,可以提供對自身項目的切入點,供其他項目代碼使用。在python環境中可以通過importlib.metadata.entry_points 函數發現所有的切入點插件,并在代碼中加載、調…

08_排序

基本概念與分類 假設含有n個記錄的序列為 { r 1 , r 2 , . . . , r n } \{r_1,r_2,...,r_n\} {r1?,r2?,...,rn?}&#xff0c;其相應的關鍵字分別為 { k 1 , k 2 , . . . , k n } \{k_1,k_2,...,k_n\} {k1?,k2?,...,kn?}&#xff0c;需確定1&#xff0c;2&#xff0c;…&…

微服務: Nacos部署安裝與properties配置

Nacos 是阿里巴巴開源的一款用于動態服務發現、配置管理和服務管理的基礎設施。Nacos 這個名稱源自于 “Dynamic Naming and Configuration Service”。它主要是用于解決微服務架構中服務發現和配置管理的問題。 Nacos 單機模式的部署安裝 1. 安裝(Windows環境) Nacos是Java…

Java線程基礎知識總結

基礎概念 Java 線程是并發編程的基礎&#xff0c;涉及到線程的創建、管理、同步以及通信。理解和掌握線程的使用對于編寫高效和響應快速的應用程序至關重要。 1. 線程基礎 線程是程序中的執行流。每個Java程序至少有一個線程 — 主線程&#xff08;main&#xff09;。通過使…

從入門到深入,Docker新手學習教程

編譯整理&#xff5c;TesterHome社區 作者&#xff5c;Ishaan Gupta 以下為作者觀點&#xff1a; Docker 徹底改變了我們開發、交付和運行應用程序的方式。它使開發人員能夠將應用程序打包到容器中 - 標準化的可執行組件&#xff0c;將應用程序源代碼與在任何環境中運行該代碼…

InspireFace-商用級的跨平臺開源人臉分析SDK

InspireFace-商用級的跨平臺開源人臉分析SDK InspireFaceSDK是由insightface開發的?款?臉識別軟件開發?具包&#xff08;SDK&#xff09;。它提供了?系列功能&#xff0c;可以滿?各種應?場景下的?臉識別需求&#xff0c;包括但不限于閘機、?臉?禁、?臉驗證等。 該S…

ubuntu22 sshd設置

專欄總目錄 一、安裝sshd服務 sudo apt updatesudo apt install -y openssh-server 二、配置sshd 使用文本編輯器打開/etc/ssh/sshd_config sudo vi /etc/ssh/sshd_config &#xff08;一&#xff09;配置sshd服務的偵聽端口 建議將ssh的偵聽端口改為7000以上的端口&#…

【bazel】快速下載教程

bazel下載鏈接&#xff1a; https://github.com/bazelbuild/bazel/releases?page11 直接在github上下載&#xff0c;會因為網絡不穩定&#xff0c;而頻繁下載錯誤 這里提供一個超級快速的方法&#xff01;&#xff01;&#xff01; 用迅雷下載&#xff01; 1.從github上復…

cpp http server/client

httplib 使用httplib庫 basedemo server.cpp #include "httplib.h" #include <iostream> using namespace httplib;int main(void) {Server svr;svr.Get("/hello", [](const Request& req, Response& res) {std::cout << "lo…

實現Java Web應用的高性能負載均衡方案

實現Java Web應用的高性能負載均衡方案 大家好&#xff0c;我是微賺淘客系統3.0的小編&#xff0c;也是冬天不穿秋褲&#xff0c;天冷也要風度的程序猿&#xff01; 在高并發的網絡環境中&#xff0c;負載均衡是確保Web應用程序高性能和可靠性的關鍵策略之一。本文將探討如何…

【力扣 - 每日一題】3115. 質數的最大距離(一次遍歷、頭尾遍歷、空間換時間、埃式篩、歐拉篩、打表)Golang實現

原題鏈接 題目描述 給你一個整數數組 nums。 返回兩個&#xff08;不一定不同的&#xff09;質數在 nums 中 下標 的 最大距離。 示例 1&#xff1a; 輸入&#xff1a; nums [4,2,9,5,3] 輸出&#xff1a; 3 解釋&#xff1a; nums[1]、nums[3] 和 nums[4] 是質數。因此答…

算法系列--分治排序|再談快速排序|快速排序的優化|快速選擇算法

前言:本文就前期學習快速排序算法的一些疑惑點進行詳細解答,并且給出基礎快速排序算法的優化版本 一.再談快速排序 快速排序算法的核心是分治思想,分治策略分為以下三步: 分解:將原問題分解為若干相似,規模較小的子問題解決:如果子問題規模較小,直接解決;否則遞歸解決子問題合…

策略模式的應用

前言 系統有一個需求就是采購員審批注冊供應商的信息時&#xff0c;會生成一個供應商的賬號&#xff0c;此時需要發送供應商的賬號信息&#xff08;賬號、密碼&#xff09;到注冊填寫的郵箱中&#xff0c;通知供應商賬號信息&#xff0c;當時很快就寫好了一個工具類&#xff0…

Python 學習中什么是字典,如何操作字典?

什么是字典 字典&#xff08;Dictionary&#xff09;是Python中的一種內置數據結構&#xff0c;用于存儲鍵值對&#xff08;key-value pair&#xff09;。字典的特點是通過鍵來快速查找值&#xff0c;鍵必須是唯一的&#xff0c;而值可以是任何數據類型。字典在其他編程語言中…

vue實現搜索文章關鍵字,滑到指定位置并且高亮

1、輸入搜索條件&#xff0c;點擊搜索按鈕 2、滑到定位到指定的搜索條件。 <template><div><div class"search_form"><el-inputv-model"searchVal"placeholder"請輸入關鍵字查詢"clearablesize"small"style&quo…

HashMap的底層實現原理詳解

HashMap是Java中最常用的集合類之一&#xff0c;其基于哈希表的Map接口實現&#xff0c;提供了快速的鍵值對存儲和檢索功能。深入理解HashMap的底層實現原理&#xff0c;對于提升編程技能、應對技術面試以及優化程序性能都具有重要意義。以下從技術難點、面試官關注點、回答吸引…

數據庫作業day3

創建一個student表用于存儲學生信息 CREATE TABLE student( id INT PRIMARY KEY, name VARCHAR(20) NOT NULL, grade FLOAT ); 向student表中添加一條新記錄 記錄中id字段的值為1&#xff0c;name字段的值為"monkey"&#xff0c;grade字段的值為98.5 insert into …

對于老百姓而言VR到底能做什么?

VR技術自誕生以來不斷發展&#xff0c;已經廣泛應用于教育、醫療、工程、軍事、航空、航海、影視、娛樂等方面&#xff0c;譬如&#xff0c;大型工程或軍事活動VR預演可以大幅度減少人力物力投入&#xff1b;在航空領域&#xff0c;航天飛行員在訓練艙中面對屏幕進行各種駕駛操…