首页 > 后端开发 > Golang > 使用 Go 构建基于 OTP 的身份验证服务器:第 3 部分

使用 Go 构建基于 OTP 的身份验证服务器:第 3 部分

DDD
发布: 2025-01-10 18:03:43
原创
805 人浏览过

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
热门教程
更多>
最新下载
更多>
网站特效
网站源码
网站素材
前端模板