This is the 24th day of my participation in the November Gwen Challenge. Check out the event details: The last Gwen Challenge 2021

Use the package

github.com/gin-contrib/sessions

github.com/gin-contrib/sessions/cookie

github.com/gin-gonic/gin

1. Write routes

  • Create a newWSGIApplication instance.
	r := gin.Default()
Copy the code
  • Set the global variable store
	store := cookie.NewStore([]byte("something-very-secret"))
Copy the code
  • Use middleware to call store in the route
	r.Use(sessions.Sessions("mysession", store))
Copy the code

2. Register a route

  • Create a basic routing group
v1 := r.Group("api/v1")
Copy the code
  • User registration routing is written in this base routing
v1 := r.Group("api/v1")
{
	// User operation
	v1.POST("user/register", api.UserRegister)
}
Copy the code

3. Register the interface

3.1 the service layer

  • inserviceSo let’s create oneuser.go

  • Write the structure of the user registration service on the service layer
//UserRegisterService manages user registration services
type UserRegisterService struct {
	Nickname  string `form:"nickname" json:"nickname" binding:"required,min=2,max=10"`
	UserName  string `form:"user_name" json:"user_name" binding:"required,min=5,max=15"`
	Password  string `form:"password" json:"password" binding:"required,min=8,max=16"`
}
Copy the code
  • Write the user registration register method on service
func (service *UserRegisterService) Register(a){}Copy the code

3.2 the API layer

  • inapiCreate a layeruser.go

  • To apply for aUserRegisterServiceA user registers a service object.
var userRegisterService service.UserRegisterService
Copy the code

However, we haven’t written this service yet. We will finish writing this interface first and then fill in this service.

  • Context-bound data
c.ShouldBind(&userRegisterService)
Copy the code
  • Call the register method of the service
res := userRegisterService.Register()
Copy the code
  • Returns the result of processing this service
c.JSON(200, res)
Copy the code
  • API layer user registration service all code
func UserRegister(c *gin.Context) {
	var userRegisterService service.UserRegisterService 
	// Create a UserRegisterService object
	if err := c.ShouldBind(&userRegisterService); err == nil {
		res := userRegisterService.Register()
		// Call the Register method on this object.
		c.JSON(200, res)
	} else {
		c.JSON(200, ErrorResponse(err))
		logging.Info(err)
	}
}
Copy the code
  • Create a common.go file and return an error

// Returns an error message ErrorResponse
func ErrorResponse(err error) serializer.Response {
	if ve, ok := err.(validator.ValidationErrors); ok {
		for _, e := range ve {
			field := conf.T(fmt.Sprintf("Field.%s", e.Field))
			tag := conf.T(fmt.Sprintf("Tag.Valid.%s", e.Tag))
			return serializer.Response{
				Status: 40001,
				Msg:    fmt.Sprintf("%s%s", field, tag),
				Error:  fmt.Sprint(err),
			}
		}
	}
	if _, ok := err.(*json.UnmarshalTypeError); ok {
		return serializer.Response{
			Status: 40001,
			Msg:    "JSON type mismatch",
			Error:  fmt.Sprint(err),
		}
	}
	return serializer.Response{
		Status: 40001,
		Msg:    "Parameter error",
		Error:  fmt.Sprint(err),
	}
}

Copy the code

3.2 serializer

  • Create a basic serialization return structure
// Response base serializer
type Response struct {
	Status int         `json:"status"`
	Data   interface{} `json:"data"`
	Msg    string      `json:"msg"`
	Error  string      `json:"error"`
}
Copy the code

4. Registration services

Next we can write register() to register the service

  • Verify the user name to see if it already exists
	model.DB.Model(&model.User{}).Where("user_name=?",service.UserName).Count(&count)
	if count == 1 {
		code = e.ErrorExistUser
		return serializer.Response{
			Status: code,
			Msg:    e.GetMsg(code),
		}
	}
Copy the code
  • Then encrypt the password
	iferr := user.SetPassword(service.Password); err ! =nil {
		logging.Info(err)
		code = e.ErrorFailEncryption
		return serializer.Response{
			Status: code,
			Msg:    e.GetMsg(code),
		}
	}
Copy the code

Note: We can write the password encryption method directly under model/user.go

const (
	PassWordCost        = 12         // Password encryption difficulty
	Active       string = "active"   // Activate the user
)

//SetPassword Sets the password
func (user *User) SetPassword(password string) error {
	bytes, err := bcrypt.GenerateFromPassword([]byte(password), PassWordCost)
	iferr ! =nil {
		return err
	}
	user.PasswordDigest = string(bytes)
	return nil
}
Copy the code
  • After confirming that all is correct, create the user
	iferr := model.DB.Create(&user).Error; err ! =nil {
		logging.Info(err)
		code = e.ErrorDatabase
		return serializer.Response{
			Status: code,
			Msg:    e.GetMsg(code),
		}
	}
Copy the code

Complete code for user registration in the service layer

func (service *UserRegisterService) Register(a) serializer.Response {
	var user model.User
	var count int
	code := e.SUCCESS
	model.DB.Model(&model.User{}).Where("user_name=?",service.UserName).Count(&count)
	if count == 1 {
		code = e.ErrorExistUser
		return serializer.Response{
			Status: code,
			Msg:    e.GetMsg(code),
		}
	}
	user = model.User{
		Nickname: service.Nickname,
		UserName: service.UserName,
		Status:   model.Active,
	}
	// Encrypt the password
	iferr := user.SetPassword(service.Password); err ! =nil {
		logging.Info(err)
		code = e.ErrorFailEncryption
		return serializer.Response{
			Status: code,
			Msg:    e.GetMsg(code),
		}
	}
	user.Avatar = "http://q1.qlogo.cn/g?b=qq&nk=294350394&s=640"
	// Create a user
	iferr := model.DB.Create(&user).Error; err ! =nil {
		logging.Info(err)
		code = e.ErrorDatabase
		return serializer.Response{
			Status: code,
			Msg:    e.GetMsg(code),
		}
	}
	return serializer.Response{
		Status: code,
		Msg:    e.GetMsg(code),
	}
}
Copy the code

In the next chapter, we write the business logic for user login.