쿼리 데이터베이스에 대한 기본적인 인증을 사용하여 가 http 인증으로 바로 이동

StackOverflow https://stackoverflow.com//questions/23006639

문제

내가 사용하려고 시도하는 갈-http-인증 마티니와-이동합니다.예제에서는 주어진 여기에서- 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()

}

비밀 함수를 사용 하드 코딩된 사용자"john".

인증이 성공적으로 수행됩니다면 나는 실행

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

물론,이것은 간단한 예제와 함께 하드 코딩된 사용자 이름과 암호를 입력합니다.

나는 이제 변경 Secret 능 이

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 ""

}

하지만 그것은 실패로 PANIC: runtime error: invalid memory address or nil pointer dereference. 는 명백하게 때문에 시도하는 인스턴스화 var db *sql.DBSecret 기능입니다.내가 전달할 수 없습니다 db *sql.DBSecret 하나 때문에 기능 auth.BasicNewAuthentication 가 기대 Secret 인수를 따르는 type func (string, string) string.

할 수 있는 방법을 구현한 데이터베이스 내 쿼리를 올바르게 반환 비밀번호에 대한 비교합니까?

도움이 되었습니까?

해결책

당신이 사용할 수 있는 간단한 클로저에 통과하기 위하여 참조하여 귀하의 DB 로 인증 기능:

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

...그리고 다음 변경 Secret 을 받아들이는 데이터베이스로 첫 번째 인수:

func Secret(db *sql.DB, user, realm string) string {
    // do your db lookup here…
}

다른 팁

대체 접근 Attilas 대답이다.정의할 수 있는 구조체,정의 Secret() 처리기에서 그것을 전달하는 참조되는 기능(이동 참조를 유지하"소유자")로 authhandler.

type SecretDb struct {
  db *DB
}
func (db *SecretDb) Secret(user, realm string) string {
 // .. use db.db here
}


func main() {
   secretdb = SecretDb{db}
   ...
   auth.NewBasicAuthenticator("example.com", secretdb.Secret)
   ...
}
라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top