使用Golang和Bcrypt实现登录注册功能的最佳实践

使用Golang和Bcrypt实现登录注册功能的最佳实践 如何使用bcrypt密码类型编写Go语言的登录注册源代码

2 回复
salt := "f8sda8asd765sadf58s7d6"
email := request.FormValue("email")
pass := request.FormValue("password")

sendpassword := []byte(pass + Salt)

err = bcrypt.CompareHashAndPassword(row.Password, sendpassword) //row.Password come from DB
if err != nil {
  fmt.Println(err)
}

更多关于使用Golang和Bcrypt实现登录注册功能的最佳实践的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html


以下是使用Golang和Bcrypt实现登录注册功能的完整示例代码:

package main

import (
    "database/sql"
    "fmt"
    "log"
    "net/http"
    
    "golang.org/x/crypto/bcrypt"
    _ "github.com/go-sql-driver/mysql"
)

var db *sql.DB

func initDB() {
    var err error
    db, err = sql.Open("mysql", "user:password@/dbname")
    if err != nil {
        log.Fatal(err)
    }
}

func hashPassword(password string) (string, error) {
    bytes, err := bcrypt.GenerateFromPassword([]byte(password), bcrypt.DefaultCost)
    return string(bytes), err
}

func checkPasswordHash(password, hash string) bool {
    err := bcrypt.CompareHashAndPassword([]byte(hash), []byte(password))
    return err == nil
}

func registerHandler(w http.ResponseWriter, r *http.Request) {
    if r.Method != "POST" {
        http.Error(w, "Method not allowed", http.StatusMethodNotAllowed)
        return
    }
    
    username := r.FormValue("username")
    password := r.FormValue("password")
    
    if username == "" || password == "" {
        http.Error(w, "Username and password required", http.StatusBadRequest)
        return
    }
    
    hashedPassword, err := hashPassword(password)
    if err != nil {
        http.Error(w, "Error hashing password", http.StatusInternalServerError)
        return
    }
    
    _, err = db.Exec("INSERT INTO users (username, password) VALUES (?, ?)", 
        username, hashedPassword)
    if err != nil {
        http.Error(w, "Error creating user", http.StatusInternalServerError)
        return
    }
    
    w.WriteHeader(http.StatusCreated)
    fmt.Fprintf(w, "User created successfully")
}

func loginHandler(w http.ResponseWriter, r *http.Request) {
    if r.Method != "POST" {
        http.Error(w, "Method not allowed", http.StatusMethodNotAllowed)
        return
    }
    
    username := r.FormValue("username")
    password := r.FormValue("password")
    
    var storedHash string
    err := db.QueryRow("SELECT password FROM users WHERE username = ?", 
        username).Scan(&storedHash)
    
    if err == sql.ErrNoRows {
        http.Error(w, "Invalid credentials", http.StatusUnauthorized)
        return
    } else if err != nil {
        http.Error(w, "Database error", http.StatusInternalServerError)
        return
    }
    
    if !checkPasswordHash(password, storedHash) {
        http.Error(w, "Invalid credentials", http.StatusUnauthorized)
        return
    }
    
    fmt.Fprintf(w, "Login successful")
}

func main() {
    initDB()
    defer db.Close()
    
    http.HandleFunc("/register", registerHandler)
    http.HandleFunc("/login", loginHandler)
    
    log.Println("Server starting on :8080")
    log.Fatal(http.ListenAndServe(":8080", nil))
}

数据库表结构示例:

CREATE TABLE users (
    id INT AUTO_INCREMENT PRIMARY KEY,
    username VARCHAR(50) UNIQUE NOT NULL,
    password VARCHAR(255) NOT NULL,
    created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);

需要安装的依赖:

go get golang.org/x/crypto/bcrypt
go get github.com/go-sql-driver/mysql

这个实现包含了以下关键点:

  1. 使用bcrypt.DefaultCost(当前为10)进行密码哈希
  2. 密码验证时使用bcrypt.CompareHashAndPassword
  3. 数据库存储哈希后的密码字符串
  4. 基本的HTTP请求处理和安全检查
  5. 使用预处理语句防止SQL注入

注意:实际生产环境中需要添加更多安全措施,如HTTPS、请求频率限制、密码强度验证等。

回到顶部