用go設計開發一個自己的輕量級登錄庫/框架吧

来源:https://www.cnblogs.com/weloe/archive/2023/05/06/17378215.html
-Advertisement-
Play Games

用go設計開發一個自己的輕量級登錄庫/框架吧 幾乎每個項目都會有登錄,退出等用戶功能,而登錄又不單僅僅是登錄,我們要考慮很多東西。 token該怎麼生成?生成什麼樣的? 是在Cookie存token還是請求頭存token?讀取的時候怎麼讀取? 允許同一個賬號被多次登錄嗎?多次登錄他們的token是一 ...


用go設計開發一個自己的輕量級登錄庫/框架吧

幾乎每個項目都會有登錄,退出等用戶功能,而登錄又不單僅僅是登錄,我們要考慮很多東西。

token該怎麼生成?生成什麼樣的?

是在Cookie存token還是請求頭存token?讀取的時候怎麼讀取?

允許同一個賬號被多次登錄嗎?多次登錄他們的token是一樣的?還是不一樣的?

登錄也有可能分成管理員登錄,用戶登錄等多種登錄類型

我們要做的就是把這些東西封裝到一起,然後能更方便的使用

而完成這些最難的就是如何設計架構了,其實要簡單的封裝一下並不難,本篇要講的就是如何進行架構的設計了。

源碼:weloe/token-go: a light login library (github.com)

Enforcer

我們可以抽象出一個供外部調用的執行器,它包括以下幾個部分

token-go/enforcer.go at master · weloe/token-go (github.com)

type Enforcer struct {
    // 從配置文件讀取配置需要
	conf         string
    // 登錄類型
	loginType    string
	config       config.TokenConfig
    // 生成token的函數
	generateFunc model.GenerateTokenFunc
    // 用於存儲數據
	adapter      persist.Adapter
    // 監聽器
	watcher      persist.Watcher
    // 用於記錄日誌
	logger       log.Logger
}

執行器的介面,包含供外部調用的方法

token-go/enforcer_interface.go at master · weloe/token-go · GitHub

var _ IEnforcer = &Enforcer{}

type IEnforcer interface {
    
	Login(id string) (string, error)
	LoginByModel(id string, loginModel *model.Login) (string, error)
	Logout() error
	IsLogin() (bool, error)
	IsLoginById(id string) (bool, error)
	GetLoginId() (string, error)

	Replaced(id string, device string) error
	Kickout(id string, device string) error

	GetRequestToken() string

	SetType(t string)
	GetType() string
	SetContext(ctx ctx.Context)
	GetAdapter() persist.Adapter
	SetAdapter(adapter persist.Adapter)
	SetWatcher(watcher persist.Watcher)
	SetLogger(logger log.Logger)
	EnableLog()
	IsLogEnable() bool
	GetSession(id string) *model.Session
	SetSession(id string, session *model.Session, timeout int64) error
}

Config

首先就是根據需求抽象出配置信息

一個是cookie的配置

token-go/cookie.go at master · weloe/token-go · GitHub

type CookieConfig struct {
	Domain   string
	Path     string
	Secure   bool
	HttpOnly bool
	SameSite string
}

一個是token的配置

token-go/token.go at master · weloe/token-go · GitHub

type TokenConfig struct {
   // TokenStyle
   // uuid | uuid-simple | random-string32 | random-string64 | random-string128
   TokenStyle string
    
   TokenName   string

   Timeout int64

   // 允許多次登錄
   IsConcurrent bool
   // 多次登錄共用一個token
   IsShare bool
   // If (IsConcurrent == true && IsShare == false)才支持配置
   // If IsConcurrent == -1, 不檢查登錄數量
   MaxLoginCount int16

   // 讀取token的方式
   IsReadBody   bool
   IsReadHeader bool
   IsReadCookie bool

   // 是否把token寫入響應頭
   IsWriteHeader bool

   CookieConfig *CookieConfig
}

Adapter

adapter是底層用來存儲數據的結構,為了相容不同的實現(不同的存儲方式),設計成一個介面。

token-go/adapter.go at master · weloe/token-go · GitHub

type Adapter interface {

	// GetStr string operate string value
	GetStr(key string) string
	// SetStr set store value and timeout
	SetStr(key string, value string, timeout int64) error
	// UpdateStr only update value
	UpdateStr(key string, value string) error
	// DeleteStr delete string value
	DeleteStr(key string) error
	// GetStrTimeout get expire
	GetStrTimeout(key string) int64
	// UpdateStrTimeout update expire time
	UpdateStrTimeout(key string, timeout int64) error

	// Get get interface{}
	Get(key string) interface{}
	// Set store interface{}
	Set(key string, value interface{}, timeout int64) error
	// Update only update interface{} value
	Update(key string, value interface{}) error
	// Delete delete interface{} value
	Delete(key string) error
	// GetTimeout get expire
	GetTimeout(key string) int64
	// UpdateTimeout update timeout
	UpdateTimeout(key string, timeout int64) error
}

Context

我們需要從請求讀取token,可能也需要寫出token,因此需要相容不同的web上下文,我們需要設計一個Context介面

token-go/context.go at master · weloe/token-go · GitHub

type Context interface {
	Request() Request
	Response() Response
	ReqStorage() ReqStorage
	MatchPath(pattern string, path string) bool
	IsValidContext() bool
}

Watcher

監聽器,用於在一些事件發生的時候進行一些其他操作。

token-go/watcher.go at master · weloe/token-go · GitHub

// Watcher event watcher
type Watcher interface {
	// Login called after login
	Login(loginType string, id interface{}, tokenValue string, loginModel *model.Login)
	// Logout called after logout
	Logout(loginType string, id interface{}, tokenValue string)
}

Logger

Logger,用於記錄日誌,方便debug等等,需要設計成可以自由開啟關閉。

token-go/logger.go at master · weloe/token-go · GitHub

type Logger interface {
	persist.Watcher

	// Enable turn on or off
	Enable(bool bool)

	// IsEnabled return if logger is enabled
	IsEnabled() bool
}

到此,項目的大致的結構就設計完成,下一篇會講講本業務的具體實現


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 分析服務 ◆ 事件分析下新增商品訂閱分析報告,幫助開發者瞭解應用內用戶付費訂閱概況,評估訂閱付費價值; ◆ 營銷分析、用戶質量、轉化分析以及過濾器中,新增廣告系列/廣告任務通過ID進行搜索的功能,通過更便捷高效的數據分析體驗,幫助開發者合理評估廣告投放的後端轉化效果。 查看詳情>> 運動健康服務 ◆ ...
  • 在Flutter中,我們有各種插件可供使用,從而實現音頻和視頻的播放功能。 例如,可以使用“text_to_speech”插件來將文字轉換為語音,使用內置的“video_player”插件輕鬆地實現視頻播放,或者使用“audioplayers”插件實現音頻播放。 對於僅需要簡單播放器功能的情況,也可 ...
  • 前端開發中涉及表單的頁面非常多,看似功能簡單,開發快速,實則占去了很大一部分時間。當某個表單包含元素過多時還會導致html代碼過多,vue文件過大。從而不容易查找、修改和維護。為了提高開發效率及降低維護成本,下麵介紹表單配置化組件的封裝原理與封裝方法。 ...
  • 這裡給大家分享我在網上總結出來的一些知識,希望對大家有所幫助 1. provide/inject provide/inject 是 Vue.js 中用於跨組件傳遞數據的一種高級技術,它可以將數據註入到一個組件中,然後讓它的所有子孫組件都可以訪問到這個數據。通常情況下,我們在父組件中使用 provid ...
  • 前兩天我寫了一個上傳下載功能 使用<el-upload>組件 當後端將文件流格式數據發送到響應裡面前端屈接受的時候 ,我們使用 <el-upload> 組件裡面的 :on-success 方法進行捕捉,使用blob進行文件下載 文件可以正常下載下來 但是打開文件損壞 我去網上尋找答案, 但大多都是說 ...
  • 本文使用 React + Three.js + React Three Fiber 技術棧,實現一個《塞爾達傳說:王國之淚》主題風格基於滾動控制的平滑滾動圖片展示頁面。通過本文的閱讀,你將學習到的知識點包括:瞭解 R3F 中 useFrame hook 及 useThree hook 基本原理及用法... ...
  • 解決的問題 避免新開發的代碼影響提測的代碼 避免生產環境出現問題後,修複後,由於代碼混亂,無法合併到生產環境 解決多個需求並行開發,並行測試,合併上線的問題 我的設計思路 流程圖工具我使用的是:diagrams.net 具體執行步驟 開發人員按需求粒度從dev建立分支 哪個需求或者哪些需求提測,就把 ...
  • 本文首發於公眾號:Hunter後端 原文鏈接:Django筆記三十六之單元測試彙總介紹 Django 的單元測試使用了 Python 的標準庫:unittest。 在我們創建的每一個 application 下麵都有一個 tests.py 文件,我們通過繼承 django.test.TestCase ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...