1 В избранное 0 Ответвления 0

OSCHINA-MIRROR/mirrors-elton

Клонировать/Скачать
body_parse_validate.md 6.5 КБ
Копировать Редактировать Web IDE Исходные данные Просмотреть построчно История
Отправлено 04.06.2025 23:59 7f2703a
description
Обработка и проверка тела запроса

В elton среде, средство body-parser считывает данные в виде байтов, но не выполняет десериализацию и проверку параметров. При использовании json для десериализации, можно выполнять только простую проверку типов параметров. В этом разделе описывается, как использовать библиотеки validator и govalidator для улучшения проверки параметров. Вы можете выбрать подходящую библиотеку по своему усмотрению.

В следующем примере показана функция аутентификации пользователя, где параметры включают имя пользователя и пароль. Ограничения для этих параметров следующие:

  • Имя пользователя: может содержать только цифры и буквы, и его длина не должна превышать 20 символов.
  • Пароль: может содержать только цифры и буквы, и его длина должна быть не менее 6 символов и не более 20 символов.

validator

package main

import (
	"encoding/json"
	"reflect"
	"regexp"

	"github.com/go-playground/validator/v10"
	"github.com/vicanso/elton"
	"github.com/vicanso/elton/middleware"
)

var (
	validate = validator.New()
)

func toString(value reflect.Value) (string, bool) {
	if value.Kind() != reflect.String {
		return "", false
	}
	return value.String(), true
}

func init() {
	rxAlphanumeric := regexp.MustCompile("^[a-zA-Z0-9]+$")

	// Добавление пользовательской проверки параметров, если возвращается false, значит параметр не соответствует требованиям
	validate.RegisterAlias("xAccount", "alphanum,max=20")
}
``````markdown
## govalidator

```go
package main

import (
	"encoding/json"

	"github.com/asaskevich/govalidator"
	"github.com/vicanso/elton"
	"github.com/vicanso/elton/middleware"
)

var (
	customTypeTagMap = govalidator.CustomTypeTagMap
)

func RegisterValidation() {
	_ = govalidator.RegisterValidation("xPassword", func(fl govalidator.FieldLevel) bool {
		value, ok := toString(fl.Field())
		if !ok {
			return false
		}
		if value == "" {
			return false
		}
		if !govalidator.RxAlphanumeric.MatchString(value) {
			return false
		}
		return len(value) <= 20 && len(value) >= 6
	})

	type loginParams struct {
		Account  string `json:"account,omitempty" validate:"xAccount"`
		Password string `json:"password,omitempty" validate:"xPassword"`
	}

	func doValidate(s interface{}, data interface{}) (err error) {
		if data != nil {
			switch data := data.(type) {
			case []byte:
				err = json.Unmarshal(data, s)
				if err != nil {
					return
				}
			default:
				buf, err := json.Marshal(data)
				if err != nil {
					return err
				}
				err = json.Unmarshal(buf, s)
				if err != nil {
					return err
				}
			}
		}
		err = govalidator.Struct(s)
		return
	}
}
``````go
func init() {
	// Добавление пользовательской проверки параметров, если возвращается false, то параметры не соответствуют требованиям
	customTypeTagMap.Set("xAccount", func(i interface{}, _ interface{}) bool {
		v, ok := i.(string)
		if !ok || v == "" {
			return false
		}
		// Если не буквы и цифры
		if !govalidator.IsAlphanumeric(v) {
			return false
		}
		// Длина аккаунта не должна превышать 20 символов
		if len(v) > 20 {
			return false
		}
		return true
	})
	customTypeTagMap.Set("xPassword", func(i interface{}, _ interface{}) bool {
		v, ok := i.(string)
		if !ok || v == "" {
			return false
		}
		// Если не буквы и цифры
		if !govalidator.IsAlphanumeric(v) {
			return false
		}
		// Длина пароля не должна превышать 20 символов и быть меньше 6 символов
		if len(v) > 20 || len(v) < 6 {
			return false
		}
		return true
	})
}
```type (
	loginParams struct {
		Account  string `json:"account,omitempty" valid:"xAccount~аккаунт допускает только цифры и буквы и не должен превышать 20 символов"`
		Password string `json:"password,omitempty" valid:"xPassword~пароль допускает только цифры и буквы и не должен превышать 20 символов и быть меньше 6 символов"`
	}
)

func doValidate(s interface{}, data interface{}) (err error) {
	// Если есть данные, то делаем десериализацию
	if data != nil {
		switch data := data.(type) {
		case []byte:
			err = json.Unmarshal(data, s)
			if err != nil {
				return
			}
		default:
			// Если данные не являются байтами, то сначала сериализуем (возможно, это map)
			buf, err := json.Marshal(data)
			if err != nil {
				return err
			}
			err = json.Unmarshal(buf, s)
			if err != nil {
				return err
			}
		}
	}
	_, err = govalidator.ValidateStruct(s)
	return
}

func main() {
	e := elton.New()
}

``````markdown
## Пример вызова

curl -XPOST -H 'Content-Type:application/json' -d '{"account":"treexie", "password": "123"}' 'http://127.0.0.1:3000/users/login'


Из приведенного выше кода видно, что можно выполнять проверку значений с помощью определенных меток проверки (обычно это проверки длины, размера и соответствия), и большинство проверок можно повторно использовать с помощью стандартных функций проверки, что делает процесс простым и удобным. Рекомендуется в реальных проектах для каждого параметра определять свои собственные правила проверки, чтобы обеспечить их корректность.

Опубликовать ( 0 )

Вы можете оставить комментарий после Вход в систему

1
https://api.gitlife.ru/oschina-mirror/mirrors-elton.git
git@api.gitlife.ru:oschina-mirror/mirrors-elton.git
oschina-mirror
mirrors-elton
mirrors-elton
master