首頁 > 後端開發 > Golang > 使用 Go 建置基於 OTP 的身份驗證伺服器:第 3 部分

使用 Go 建置基於 OTP 的身份驗證伺服器:第 3 部分

DDD
發布: 2025-01-10 18:03:43
原創
806 人瀏覽過

Build an OTP-Based Authentication Server with Go: Part 3

本期詳細介紹了透過 Twilio 實現 OTP 傳送、使用 goroutine 優化 OTP 非同步發送,以及建立強大的基於令牌的身份驗證系統。

使用 Twilio 發送 OTP

使用 Twilio 訊息 API 傳送 OTP 的核心功能如下所示:

<code class="language-go">func (app *application) sendOTPViaTwilio(otp, phoneNumber string) error {
    client := twilio.NewRestClientWithParams(twilio.ClientParams{
        Username: os.Getenv("TWILIO_SID"),
        Password: os.Getenv("TWILIO_API_KEY"),
    })

    params := &api.CreateMessageParams{}
    params.SetBody(fmt.Sprintf(
        "Thank you for choosing Cheershare! Your one-time password is %v.",
        otp,
    ))
    params.SetFrom(os.Getenv("TWILIO_PHONE_NUMBER"))
    params.SetTo(fmt.Sprintf("+91%v", phoneNumber))

    const maxRetries = 3
    var lastErr error

    for attempt := 1; attempt <= maxRetries; attempt++ {
        resp, err := client.SendSms(params)
        if err == nil {
            app.logger.Printf("Message SID: %s", resp.Sid)
            return nil
        }
        lastErr = err
        time.Sleep(time.Duration(attempt) * 100 * time.Millisecond)
    }

    return fmt.Errorf("failed to send OTP after %d retries: %w", maxRetries, lastErr)
}</code>
登入後複製

此函數利用 Twilio 的 Go SDK 發送訊息。 from 號碼是預先配置的 Twilio 號碼。 包含重試機制以確保可靠性。

使用 Goroutine 進行非同步 OTP 傳送

順序 OTP 發送會影響伺服器效能。 此解決方案涉及利用 goroutine 來同時處理 OTP 傳遞。 application 結構已更新:

<code class="language-go">type application struct {
    wg     sync.WaitGroup
    config config
    models data.Models
    logger *log.Logger
    cache  *redis.Client
}</code>
登入後複製

輔助函數有助於後台任務執行:

<code class="language-go">func (app *application) background(fn func()) {
    app.wg.Add(1)
    go func() {
        defer app.wg.Done()
        defer func() {
            if err := recover(); err != nil {
                app.logger.Printf("Error in background function: %v\n", err)
            }
        }()
        fn()
    }()
}</code>
登入後複製

這使用 sync.WaitGroup 來管理 goroutine,確保在關閉之前完成。

資料庫令牌表

建立一個新的資料庫表來儲存使用者令牌:

<code class="language-sql">-- 000002_create-token.up.sql
CREATE TABLE IF NOT EXISTS tokens (
    hash bytea PRIMARY KEY,
    user_id bigint NOT NULL REFERENCES users ON DELETE CASCADE,
    expiry timestamp(0) with time zone NOT NULL,
    scope text NOT NULL
);

-- 000002_create-token.down.sql
DROP TABLE IF EXISTS tokens;</code>
登入後複製

此表儲存雜湊令牌、使用者 ID、到期時間和令牌範圍。 資料庫遷移是使用migrate.

執行的

代幣模型與功能

data/models.go 檔案包含用於令牌產生、插入和擷取的函數:

<code class="language-go">// ... (other imports) ...

package data

// ... (other code) ...

func generateToken(userId int64, ttl time.Duration, scope string) (*Token, error) {
    // ... (token generation logic) ...
}

func (m TokenModel) Insert(token *Token) error {
    // ... (database insertion logic) ...
}

func (m TokenModel) DeleteAllForUser(scope string, userID int64) error {
    // ... (database deletion logic) ...
}

func (m TokenModel) New(userId int64, ttl time.Duration, scope string) (*Token, error) {
    // ... (token creation and insertion logic) ...
}</code>
登入後複製

此程式碼處理令牌建立、雜湊和資料庫互動。 New 函數建立並儲存新令牌。

註冊處理程序更新

cmd/api/user.go 檔案的註冊處理程序已修改為在成功 OTP 驗證後頒發令牌:

<code class="language-go">// ... (other functions) ...

func (app *application) handleUserSignupAndVerification(w http.ResponseWriter, r *http.Request) {
    // ... (input parsing and validation) ...

    // ... (OTP generation and sending logic) ...

    // ... (OTP verification logic) ...

    // ... (user creation or retrieval) ...

    token, err := app.generateTokenForUser(user.ID)
    if err != nil {
        // ... (error handling) ...
    }

    // ... (success response with token) ...
}</code>
登入後複製

這將令牌產生整合到註冊流程中。

中間件層

三個中間件層增強了安全性和請求處理:recoverPanicauthenticaterequireAuthenticatedUser。 這些已實現並應用於路由,如原文所示。 上下文管理函數(contextSetUsercontextGetUser)用於在請求上下文中儲存和檢索使用者資料。

伺服器設定整合了這些中間件,範例展示如何使用requireAuthenticatedUser保護路由。 未來的增強功能包括文件上傳、正常關閉和指標整合。 完整的程式碼可以在 GitHub 上找到。

以上是使用 Go 建置基於 OTP 的身份驗證伺服器:第 3 部分的詳細內容。更多資訊請關注PHP中文網其他相關文章!

來源:php.cn
本網站聲明
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn
熱門教學
更多>
最新下載
更多>
網站特效
網站源碼
網站素材
前端模板