模擬開發授權平臺

這次只是實現應用的curd和公私鑰的校驗以及第三方的通知dmeo項目,大家可以拓開視野來編寫

進入主題

項目鏈接:桌角的眼鏡/develop_auth_platform

直接下拉并運行就行 回調應用代碼在test包中

回調應用測試代碼

package mainimport ("encoding/json""fmt""io""log""net/http""time"
)func main() {// 設置路由http.HandleFunc("/callback", callbackHandler)http.HandleFunc("/", homeHandler)// 配置服務器server := &http.Server{Addr:         ":8089",ReadTimeout:  5 * time.Second,WriteTimeout: 10 * time.Second,}// 啟動服務器fmt.Printf("🚀 服務已啟動,監聽端口 8089\n")fmt.Printf("👉 測試接口: curl -X POST http://localhost:8089/callback -d '{\"message\":\"test\"}'\n")if err := server.ListenAndServe(); err != nil {log.Fatalf("? 服務器啟動失敗: %v", err)}
}// 回調接口處理器
func callbackHandler(w http.ResponseWriter, r *http.Request) {// 打印請求基本信息fmt.Printf("\n=== 收到回調請求 ===\n")fmt.Printf("時間: %s\n", time.Now().Format(time.RFC3339))fmt.Printf("方法: %s\n", r.Method)fmt.Printf("來源IP: %s\n", r.RemoteAddr)fmt.Printf("請求頭: %v\n", r.Header)// 根據Content-Type處理不同格式的請求體contentType := r.Header.Get("Content-Type")var body interface{}switch contentType {case "application/json":var jsonBody map[string]interface{}if err := json.NewDecoder(r.Body).Decode(&jsonBody); err != nil {http.Error(w, "無效的JSON數據", http.StatusBadRequest)return}body = jsonBodydefault:// 其他類型直接讀取原始數據data, err := io.ReadAll(r.Body)if err != nil {http.Error(w, "讀取請求體失敗", http.StatusBadRequest)return}body = string(data)}// 打印請求體fmt.Printf("請求體: %+v\n", body)fmt.Printf("===================\n")// 返回成功響應w.Header().Set("Content-Type", "application/json")json.NewEncoder(w).Encode(map[string]interface{}{"status":  "success","message": "回調已接收","data":    body,})
}// 首頁處理器
func homeHandler(w http.ResponseWriter, r *http.Request) {if r.URL.Path != "/" {http.NotFound(w, r)return}w.Header().Set("Content-Type", "text/plain")fmt.Fprintf(w, "回調服務運行中\n請訪問 /callback 接口")
}

?項目的簡易結構

核心部分?

Application的curd

/api/v1/下的application.go

package v1import ("github.com/gin-gonic/gin""github.com/spectacleCase/develop_auth_platform/global""github.com/spectacleCase/develop_auth_platform/models"request "github.com/spectacleCase/develop_auth_platform/models/request"
)type Application struct{}func (Application) Create() gin.HandlerFunc {return func(c *gin.Context) {var NewApp request.Createif err := c.ShouldBind(&NewApp); err != nil {models.FailWithMessage("參數有誤", c)return}id, err := models.GenerateID()if err != nil {models.FailWithMessage(err.Error(), c)return}// 得到公私鑰prKey, puKey, err := models.GetDefaultKeyPair()if err != nil {models.FailWithMessage(err.Error(), c)return}global.ApplicationList = append(global.ApplicationList, &models.Application{Id:          id,Name:        NewApp.Name,CallbackUrl: NewApp.CallbackUrl,PrKey:       prKey,PuKey:       puKey,})models.Ok(c)return}
}func (Application) Get() gin.HandlerFunc {return func(c *gin.Context) {models.OkWithData(global.ApplicationList, c)return}
}func (Application) Update() gin.HandlerFunc {return func(c *gin.Context) {var updateApp request.Updateif err := c.ShouldBind(&updateApp); err != nil {models.FailWithMessage("參數有誤", c)return}for index, app := range global.ApplicationList {if app == nil {continue // 跳過 nil 指針}if app.Id == updateApp.Id {app.Name = updateApp.Nameapp.CallbackUrl = updateApp.CallbackUrlglobal.ApplicationList[index] = app}models.Ok(c)return}models.FailWithMessage("錯誤的參數", c)return}
}func (Application) Delete() gin.HandlerFunc {return func(c *gin.Context) {var delApp request.Deleteif err := c.ShouldBind(&delApp); err != nil {models.FailWithMessage("參數有誤", c)return}for index, app := range global.ApplicationList {if app == nil {continue // 跳過 nil 指針}if app.Id == delApp.Id {global.ApplicationList[index] = nil}models.Ok(c)return}models.FailWithMessage("錯誤的參數", c)return}
}

/models下的application.go?

package modelsimport ("crypto/rand""crypto/rsa""crypto/x509""encoding/base64""encoding/pem""fmt"
)type Application struct {Id          string `json:"id"`Name        string `json:"name"`PrKey       string `json:"-"`     // 私鑰(JSON 序列化時忽略)PuKey       string `json:"puKey"` // 公鑰SerPuKey    string `json:"serPuKey"`CallbackUrl string `json:"callbackUrl"` // 回調地址
}// GenerateID 生成唯一應用ID (UUID簡化版)
func GenerateID() (string, error) {const length = 16 // 16字節 = 128位b := make([]byte, length)if _, err := rand.Read(b); err != nil {return "", fmt.Errorf("生成ID失敗: %v", err)}return base64.URLEncoding.EncodeToString(b), nil
}// GenerateKeyPair 生成RSA公私鑰對
func GenerateKeyPair(bits int) (prKey, puKey string, err error) {privateKey, err := rsa.GenerateKey(rand.Reader, bits)if err != nil {return "", "", fmt.Errorf("密鑰生成失敗: %v", err)}// 編碼私鑰privateKeyBytes := x509.MarshalPKCS1PrivateKey(privateKey)privateKeyPEM := pem.EncodeToMemory(&pem.Block{Type:  "RSA PRIVATE KEY",Bytes: privateKeyBytes,})// 編碼公鑰publicKeyBytes, err := x509.MarshalPKIXPublicKey(&privateKey.PublicKey)if err != nil {return "", "", fmt.Errorf("公鑰編碼失敗: %v", err)}publicKeyPEM := pem.EncodeToMemory(&pem.Block{Type:  "PUBLIC KEY",Bytes: publicKeyBytes,})return string(privateKeyPEM), string(publicKeyPEM), nil
}// GetDefaultKeyPair 獲取默認強度的密鑰對 (2048位)
func GetDefaultKeyPair() (string, string, error) {return GenerateKeyPair(2048)
}// VerifyKeyPair 驗證公私鑰是否匹配
func VerifyKeyPair(prKey, puKey string) bool {block, _ := pem.Decode([]byte(prKey))if block == nil {return false}privateKey, err := x509.ParsePKCS1PrivateKey(block.Bytes)if err != nil {return false}pubBlock, _ := pem.Decode([]byte(puKey))if pubBlock == nil {return false}pubKey, err := x509.ParsePKIXPublicKey(pubBlock.Bytes)if err != nil {return false}rsaPubKey, ok := pubKey.(*rsa.PublicKey)if !ok {return false}return privateKey.PublicKey.Equal(rsaPubKey)
}

測試截圖

?

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

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

相關文章

STM32 USART串口

一、通信接口 二、串口通信 串口是一種應用十分廣泛的通訊接口,串口成本低、容易使用、通信線路簡單,可實現兩個設備的互相通信單片機的串口可以使單片機與單片機、單片機與電腦、單片機與各式各樣的模塊互相通信,極大地擴展了單片機的應用…

uniapp開發06-視頻組件video的使用注意事項

uniapp開發-視頻組件video的使用注意事項&#xff01;實際項目開發中&#xff0c;經常會遇到視頻播放的業務需求。下面簡單講解一下&#xff0c;uniapp官方提供的視頻播放組件video的常見參數和實際效果。 1&#xff1a;先看代碼&#xff1a; <!--視頻組件的使用展示-->…

【爬蟲】微博熱搜機

第一個下面一點&#xff1a; js代碼&#xff1a; const n require("crypto-js");let s n.SHA1(n.enc.Utf8.parse("tSdGtmwh49BcR1irt18mxG41dGsBuGKS")) , a n.enc.Hex.parse(s.toString(n.enc.Hex).substr(0, 32));function h(t) {let e (i t Stri…

軟考 系統架構設計師系列知識點之雜項集萃(51)

接前一篇文章&#xff1a;軟考 系統架構設計師系列知識點之雜項集萃&#xff08;50&#xff09; 第80題 設三個煤場A1、A2、A3分別能供應煤7、12、11萬噸&#xff0c;三個工廠B1、B2、B3分別需要10、10、10萬噸&#xff0c;從各煤場到各工廠運煤的單價&#xff08;百元/噸&…

npm,yarn,pnpm,cnpm,nvm,npx包管理器常用命令

前端比較主流的包管理器主要有三個npm&#xff0c;yarn&#xff0c;pnpm 多層級依賴&#xff0c;通常發生在依賴之間存在復雜的版本要求時 包 A 依賴于包 B1.0.0 包 B 依賴于包 C2.0.0 另一個包 D 也依賴于 C3.0.0 一、NPM (Node Package Manager) https://www.npmjs.cn/…

科普簡潔版:同態加密——密碼學的未來瑰寶

文章目錄 一、同態加密的基本概念1.1 什么是同態加密1.2 同態加密的數學本質1.3 同態加密的類型 二、主要同態加密方案詳解2.1 ElGamal加密2.2 Paillier加密2.3 Gentry的完全同態加密方案2.4 BGV方案2.5 BFV方案2.6 CKKS方案 三、同態加密的關鍵技術3.1 噪聲管理技術3.2 多項式…

力扣第448場周賽

賽時成績如下: 這應該是我力扣周賽的最好成績了(雖然還是三題) 1. 兩個數字的最大乘積 給定一個正整數 n。 返回 任意兩位數字 相乘所得的 最大 乘積。 注意&#xff1a;如果某個數字在 n 中出現多次&#xff0c;你可以多次使用該數字。 示例 1&#xff1a; 輸入&#xff1…

(一)Modular Monolith Architecture(項目結構/.net項目初始化/垂直切片架構)

文章目錄 項目地址一、項目結構1.1 Modules1. Events 模塊2. Users 模塊3. Ticketing 模塊4. Attendance 模塊1.2 數據庫模塊1.3 模塊架構選擇1. 全是Clean Architecture2. 分別使用不同的架構二、初始化項目2.1 本地創建項目結構1. 創建空的solution2. 添加基礎配置3. 創建git…

Java常用組件之Redis經典面試題(一)

大家好&#xff0c;今天為大家帶來Java項目中&#xff0c;幾乎必不可少的組件之一-Redis的一些常見面試題&#xff0c;幫忙近期需要面試的朋友們來一個理論基礎突擊&#xff01; 一、數據類型 1.Redis的常用數據類型有哪些 ? 難易程度&#xff1a;☆☆☆ 出現頻率&#xff1a;…

2025.5.4總結

今天去光谷步行街逛了一下&#xff0c;感覺熟悉又陌生&#xff0c;說熟悉是因為初二的時候來過武漢光谷&#xff0c;盡管過去了8年時間&#xff0c;但絲毫不影響標志性建筑的存在&#xff0c;也陌生是商場的建筑風格真實氣派&#xff0c;感覺進入了一座城堡&#xff0c;在里面都…

神經網絡在專家系統中的應用:從符號邏輯到連接主義的融合創新

自人工智能作為一個學科面世以來&#xff0c;關于它的研究途徑就存在兩種不同的觀點。一種觀點主張對人腦的結構及機理開展研究&#xff0c;并通過大規模集成簡單信息處理單元來模擬人腦對信息的處理&#xff0c;神經網絡是這一觀點的代表。關于這方面的研究一般被稱為連接機制…

Doo全自動手機殼定制系統

Doo全自動手機殼定制系統 項目概述 Doo全自動手機殼定制系統是一個完整的手機殼定制解決方案&#xff0c;支持多端應用&#xff0c;包括服務端、客戶端、管理后臺等多個組件。系統采用現代化的技術棧&#xff0c;提供完整的手機殼定制、訂單管理、用戶管理等功能。 目錄結構…

PageOffice在線打開word文件,并實現切換文件

本示例關鍵代碼的編寫位置&#xff0c;請參考“PageOffice 開發者中心-快速起步–開始 - 快速上手”里您所使用的開發語言框架的最簡集成代碼 注意 本文中展示的代碼均為關鍵代碼&#xff0c;復制粘貼到您的項目中&#xff0c;按照實際的情況&#xff0c;例如文檔路徑&#xff…

Webug4.0靶場通關筆記12- 第17關 文件上傳之前端攔截(3種方法)

目錄 一、文件上傳前端攔截原理 二、第17關 文件上傳(前端攔截) 1.打開靶場 2.構造php腳本 3.源碼分析 &#xff08;1&#xff09;js源碼 &#xff08;2&#xff09;服務器源碼 &#xff08;3&#xff09;總結 4.滲透實戰 &#xff08;1&#xff09;禁用js法 &#…

高性能 WEB 服務器 Nginx:多虛擬主機實現!

Nginx 配置多虛擬主機實現 多虛擬主機是指在一臺 Nginx 服務器上配置多個網站 在 Nginx 中&#xff0c;多虛擬主機有三種實現方式&#xff1a; 基于IP地址實現多虛擬主機 基于端口號實現多虛擬主機 基于域名實現多虛擬主機 1 基于域名實現多虛擬主機 在 Nginx 中配置多個…

網星安全AWS攻防方案,重磅發布!

AWS介紹 AWS&#xff08;Amazon Web Services&#xff09; 是 Amazon 提供的云計算平臺&#xff0c;提供了廣泛的云服務&#xff0c;包括計算、存儲、數據庫、網絡、安全、人工智能、大數據處理等功能&#xff0c;幫助企業和開發者構建、部署和管理應用程序。AWS 是全球最大的…

qt的containers里的QToolBox和QTabWidget

Tool Box是一個多層次的折疊面板&#xff0c;通常用于組織多個可展開/折疊的面板組&#xff0c;每個面板有一個標題欄&#xff0c;用戶點擊標題欄可以展開或收起內容區域。比如設置界面中的分類選項&#xff0c;每個分類可以展開查看詳細內容。這樣能節省空間&#xff0c;讓界面…

【神經網絡與深度學習】深度學習中的生成模型簡介

深度學習中的生成模型 openai 的一個古早介紹 引言 深度學習中的生成模型能夠學習數據分布并生成新數據&#xff0c;在人工智能的多個領域中都有重要應用。不同類型的生成模型在原理和結構上各有特點&#xff0c;適用于不同的任務&#xff0c;如圖像生成、文本生成和時間序列…

js獲取明天日期、Vue3大菠蘿 Pinia的使用

直接上代碼 const today new Date(2019, 2, 28) const finalDate new Date(today) finalDate.setDate(today.getDate() 3)console.log(finalDate) // 31 March 2019 安裝 yarn add pinia # or with npm npm install pinia創建第一個store倉庫 1、在src目錄下創建store目錄…

存儲過程補充——定義條件、處理程序及游標使用

文章目錄 1. 定義條件與處理程序1.1 定義條件1.2 處理程序1.3 案例演示 2. 游標2.1 使用游標第一步&#xff0c;聲明游標第二步&#xff0c;打開游標第三步&#xff0c;使用游標&#xff08;從游標中取得數據&#xff09;第四步&#xff0c;關閉游標 2.2 舉例2.3 小結 在 MySQL…