Rumah > pembangunan bahagian belakang > Golang > Bina Pelayan Pengesahan Berasaskan OTP dengan Go: Bahagian 3

Bina Pelayan Pengesahan Berasaskan OTP dengan Go: Bahagian 3

DDD
Lepaskan: 2025-01-10 18:03:43
asal
806 orang telah melayarinya

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

Butiran ansuran ini melaksanakan penghantaran OTP melalui Twilio, mengoptimumkan penghantaran OTP secara tidak segerak menggunakan goroutin dan mewujudkan sistem pengesahan berasaskan token yang mantap.

Menghantar OTP dengan Twilio

Fungsi teras untuk menghantar OTP menggunakan API pemesejan Twilio dibentangkan di bawah:

<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>
Salin selepas log masuk

Fungsi ini menggunakan Twilio's Go SDK untuk menghantar mesej. Nombor from ialah nombor Twilio yang diprakonfigurasikan. Mekanisme cuba semula disertakan untuk kebolehpercayaan.

Penghantaran OTP tak segerak dengan Goroutines

Penghantaran OTP berurutan menghalang prestasi pelayan. Penyelesaiannya melibatkan penggunaan goroutine untuk mengendalikan penghantaran OTP secara serentak. Struktur application dikemas kini:

<code class="language-go">type application struct {
    wg     sync.WaitGroup
    config config
    models data.Models
    logger *log.Logger
    cache  *redis.Client
}</code>
Salin selepas log masuk

Fungsi pembantu memudahkan pelaksanaan tugas latar belakang:

<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>
Salin selepas log masuk

Ini menggunakan sync.WaitGroup untuk mengurus goroutine, memastikan siap sebelum ditutup.

Jadual Token Pangkalan Data

Jadual pangkalan data baharu dicipta untuk menyimpan token pengguna:

<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>
Salin selepas log masuk

Jadual ini menyimpan token cincang, ID pengguna, masa tamat tempoh dan skop token. Penghijrahan pangkalan data dilakukan menggunakan migrate.

Model dan Fungsi Token

Fail data/models.go termasuk fungsi untuk penjanaan, penyisipan dan pengambilan token:

<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>
Salin selepas log masuk

Kod ini mengendalikan penciptaan token, pencincangan dan interaksi pangkalan data. Fungsi New mencipta dan menyimpan token baharu.

Kemas Kini Pengendali Pendaftaran

Pengendali pendaftaran fail cmd/api/user.go diubah suai untuk mengeluarkan token apabila pengesahan OTP berjaya:

<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>
Salin selepas log masuk

Ini menyepadukan penjanaan token ke dalam aliran pendaftaran.

Lapisan Peranti Tengah

Tiga lapisan perisian tengah meningkatkan keselamatan dan pengendalian permintaan: recoverPanic, authenticate dan requireAuthenticatedUser. Ini dilaksanakan dan digunakan pada laluan seperti yang ditunjukkan dalam teks asal. Fungsi pengurusan konteks (contextSetUser dan contextGetUser) digunakan untuk menyimpan dan mendapatkan semula data pengguna dalam konteks permintaan.

Konfigurasi pelayan menyepadukan perisian tengah ini dan contoh menunjukkan cara melindungi laluan menggunakan requireAuthenticatedUser. Penambahbaikan masa hadapan termasuk memuat naik fail, penutupan anggun dan penyepaduan metrik. Kod lengkap tersedia di GitHub.

Atas ialah kandungan terperinci Bina Pelayan Pengesahan Berasaskan OTP dengan Go: Bahagian 3. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!

sumber:php.cn
Kenyataan Laman Web ini
Kandungan artikel ini disumbangkan secara sukarela oleh netizen, dan hak cipta adalah milik pengarang asal. Laman web ini tidak memikul tanggungjawab undang-undang yang sepadan. Jika anda menemui sebarang kandungan yang disyaki plagiarisme atau pelanggaran, sila hubungi admin@php.cn
Tutorial Popular
Lagi>
Muat turun terkini
Lagi>
kesan web
Kod sumber laman web
Bahan laman web
Templat hujung hadapan