쿼리 데이터베이스에 대한 기본적인 인증을 사용하여 가 http 인증으로 바로 이동
-
21-12-2019 - |
문제
내가 사용하려고 시도하는 갈-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.DB
에 Secret
기능입니다.내가 전달할 수 없습니다 db *sql.DB
로 Secret
하나 때문에 기능 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)
...
}