ZBLOG

go 写用户认证的demo,如何将整个认证链整合起来,写出优雅的代码

在 Go 中实现用户认证的过程可以分为几个步骤。这里是一个简单的用户认证示例,包括注册、登录以及中间件来保护需要认证的路由。

我们将使用以下组件:

  • gin 框架来处理 HTTP 请求
  • gorm 作为 ORM 来与数据库交互(SQLite)
  • bcrypt 来进行密码哈希

首先,确保你已安装所需的包:

  1. go get github.com/gin-gonic/gin
  2. go get gorm.io/gorm
  3. go get gorm.io/driver/sqlite
  4. go get golang.org/x/crypto/bcrypt

接下来是完整的代码示例:

  1. package main
  2. import (
  3. "fmt"
  4. "log"
  5. "net/http"
  6. "github.com/gin-gonic/gin"
  7. "gorm.io/driver/sqlite"
  8. "gorm.io/gorm"
  9. )
  10. var db *gorm.DB
  11. type User struct {
  12. ID uint `json:"id" gorm:"primaryKey"`
  13. Username string `json:"username"`
  14. Password string `json:"password"`
  15. }
  16. // 初始化数据库
  17. func setupDatabase() {
  18. var err error
  19. db, err = gorm.Open(sqlite.Open("users.db"), &gorm.Config{})
  20. if err != nil {
  21. log.Fatal("Failed to connect to database")
  22. }
  23. db.AutoMigrate(&User{})
  24. }
  25. // 哈希密码
  26. func hashPassword(password string) (string, error) {
  27. bytes, err := bcrypt.GenerateFromPassword([]byte(password), bcrypt.DefaultCost)
  28. return string(bytes), err
  29. }
  30. // 检查密码是否匹配
  31. func checkPassword(hashedPwd, plainPwd string) bool {
  32. err := bcrypt.CompareHashAndPassword([]byte(hashedPwd), []byte(plainPwd))
  33. return err == nil
  34. }
  35. // 注册用户
  36. func register(c *gin.Context) {
  37. var user User
  38. if err := c.ShouldBindJSON(&user); err != nil {
  39. c.JSON(http.StatusBadRequest, gin.H{"error": "Invalid input"})
  40. return
  41. }
  42. hashedPassword, _ := hashPassword(user.Password)
  43. user.Password = hashedPassword
  44. result := db.Create(&user)
  45. if result.Error != nil {
  46. c.JSON(http.StatusInternalServerError, gin.H{"error": "Could not create user"})
  47. return
  48. }
  49. c.JSON(http.StatusOK, gin.H{"message": "User registered successfully!"})
  50. }
  51. // 登录用户并返回 token(简化版,不做 token 签发)
  52. func login(c *gin.Context) {
  53. var user User
  54. if err := c.ShouldBindJSON(&user); err != nil {
  55. c.JSON(http.StatusBadRequest, gin.H{"error": "Invalid input"})
  56. return
  57. }
  58. var existingUser User
  59. if result := db.Where("username = ?", user.Username).First(&existingUser); result.Error != nil {
  60. c.JSON(http.StatusUnauthorized, gin.H{"error": "Invalid username or password"})
  61. return
  62. }
  63. if !checkPassword(existingUser.Password, user.Password) {
  64. c.JSON(http.StatusUnauthorized, gin.H{"error": "Invalid username or password"})
  65. return
  66. }
  67. c.JSON(http.StatusOK, gin.H{"message": "Login successful!"})
  68. }
  69. // 受保护的路由示例,仅供演示用(无实际验证逻辑)
  70. func protectedRoute(c *gin.Context) {
  71. c.JSON(http.StatusOK, gin.H{"message": "This is a protected route!"})
  72. }
  73. func main() {
  74. r := gin.Default()
  75. setupDatabase()
  76. r.POST("/register", register)
  77. r.POST("/login", login)
  78. protected := r.Group("/protected")
  79. protected.Use(authMiddleware())
  80. protected.GET("/", protectedRoute)
  81. r.Run(":8080")
  82. }
  83. // 示例中间件,用于验证用户认证状态(未具体实现)
  84. func authMiddleware() gin.HandlerFunc {
  85. return func(c *gin.Context) {
  86. // 在这里通常会检查JWT或Session等方式,下面仅做示例处理。
  87. // 假设所有请求都通过验证,可以根据需要调整逻辑
  88. // 如果没有认证则直接返回401 Unauthorized响应。
  89. c.Next()
  90. }
  91. }

代码说明:

  1. 数据库初始化:我们使用 SQLite 数据库来存储用户数据,并自动迁移 User 结构体到数据库。
  2. 用户注册:接收 JSON 输入,哈希密码并存储到数据库。
  3. 用户登录:检查用户名和密码,如果成功则返回登录成功的信息。
  4. 保护路由:提供一个受保护的路由,实际应用中应该添加真实的身份验证逻辑(如 JWT 验证)。
  5. 中间件:可以在其中实现对每个请求进行身份验证。

注意事项:

  • 本示例中的授权机制非常基础。建议使用 JWT 或其他方法来管理会话和授权。
  • 在生产环境中,请确保正确地处理错误和敏感信息。
  • 使用 HTTPS 确保安全传输数据。

这个简单而优雅的结构为你整合了基本的用户认证链条,你可以根据自己的需求进一步扩展功能。


内容由零声教学AI助手提供,问题来源于学员提问

本站部分文章来源于网络,版权归原作者所有,如有侵权请联系站长删除。
转载请注明出处:https://golang.0voice.com/?id=20424

分享:
扫描分享到社交APP
上一篇
下一篇
发表列表
游客 游客
此处应有掌声~
评论列表

还没有评论,快来说点什么吧~

联系我们

在线咨询: 点击这里给我发消息

微信号:3007537140

上班时间: 10:30-22:30

关注我们
x

注册

已经有帐号?