dongwoqin7034 2014-04-11 07:50
浏览 36
已采纳

使用带有martini-go的go-http-auth在数据库中查询基本身份验证

I am attempting to use go-http-auth with martini-go. In the example given here - https://github.com/abbot/go-http-auth

package main

import (
        auth "github.com/abbot/go-http-auth"
        "fmt"
        "net/http"
)

func Secret(user, realm string) string {
        if user == "john" {
                // password is "hello"
                return "$1$dlPL2MqE$oQmn16q49SqdmhenQuNgs1"
        }
        return ""
}

func handle(w http.ResponseWriter, r *auth.AuthenticatedRequest) {
        fmt.Fprintf(w, "<html><body><h1>Hello, %s!</h1></body></html>", r.Username)
}


func main() {
    db, err := sql.Open("postgres", "postgres://blabla:blabla@localhost/my_db")
    authenticator := auth.NewBasicAuthenticator("example.com", Secret)
    m := martini.Classic()
    m.Map(db)
    m.Get("/users", authenticator.Wrap(MyUserHandler))
    m.Run()

}

The Secret function is using a hardcoded user "john".

The authentication is successful when I execute

curl --user john:hello localhost:3000/users

Obviously, this is a trivial example with hardcoded username and password.

I am now changing the Secret function to this

func Secret(user, realm string) string {

    fmt.Println("Executing Secret")

    var db *sql.DB

    var (
        username string
        password string
    )

    err := db.QueryRow("select username, password from users where username = ?", user).Scan(&username, &password)

    if err == sql.ErrNoRows {
        return ""
    }

    if err != nil {
        log.Fatal(err)
    }
    //if user == "john" {
        //// password is "hello"
        //return "$1$dlPL2MqE$oQmn16q49SqdmhenQuNgs1"
    //}
    //return ""
    return ""

}

But it fails with PANIC: runtime error: invalid memory address or nil pointer dereference. Which is obviously because I am attempting to instantiate var db *sql.DB in the Secret function. I cannot pass db *sql.DB into the Secret function either because auth.BasicNewAuthentication is expecting a Secret argument that conforms to type func (string, string) string.

How can I implement my database query correctly and return the password for comparison?

  • 写回答

2条回答 默认 最新

  • dongze8698 2014-04-11 09:25
    关注

    You can use a simple closure to pass in a reference to your DB to the authenticator function:

    authenticator := auth.NewBasicAuthenticator("example.com", func(user, realm string) string {
        return Secret(db, user, realm)
    })
    

    …and then change your Secret to accept the database as the first argument:

    func Secret(db *sql.DB, user, realm string) string {
        // do your db lookup here…
    }
    
    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论
查看更多回答(1条)

报告相同问题?

悬赏问题

  • ¥20 测距传感器数据手册i2c
  • ¥15 RPA正常跑,cmd输入cookies跑不出来
  • ¥15 求帮我调试一下freefem代码
  • ¥15 matlab代码解决,怎么运行
  • ¥15 R语言Rstudio突然无法启动
  • ¥15 关于#matlab#的问题:提取2个图像的变量作为另外一个图像像元的移动量,计算新的位置创建新的图像并提取第二个图像的变量到新的图像
  • ¥15 改算法,照着压缩包里边,参考其他代码封装的格式 写到main函数里
  • ¥15 用windows做服务的同志有吗
  • ¥60 求一个简单的网页(标签-安全|关键词-上传)
  • ¥35 lstm时间序列共享单车预测,loss值优化,参数优化算法