From ca6af5052d83169b84db7c6f9e66178bc1896681 Mon Sep 17 00:00:00 2001 From: Andrey Krasavin Date: Mon, 1 Apr 2019 12:29:52 +0300 Subject: [PATCH] typos fix & code formatting --- ru/04.4.md | 58 +++++++++++++++++++++++++++--------------------------- 1 file changed, 29 insertions(+), 29 deletions(-) diff --git a/ru/04.4.md b/ru/04.4.md index 41578519..ca2e70c0 100644 --- a/ru/04.4.md +++ b/ru/04.4.md @@ -1,11 +1,11 @@ # 4.4 Дублирование отправки -Не знаю, встречали ли Вы, как на каком-либо блоге или форуме размещено несколько постов подряд с одинаковым содержимым, но я могу сказать Вам, что это происходит по причине того, что отправка постов дублируется пользователем. Это может произойти по многим причинам; иногда пользователь отправляет форму двойным щелчком, или он после отправки решает исправить содержимое поста и нажимает кнопку браузера "Назад". А иногда это - намереные действия злоумышленников. Понятно, что дублирование отправки может привести ко многим проблемам. Поэтому нам нужно принимать эффективные меры для его предотвращения. +Не знаю, встречали ли Вы, как на каком-либо блоге или форуме размещено несколько постов подряд с одинаковым содержимым, но я могу сказать Вам, что это происходит по причине того, что отправка постов дублируется пользователем. Это может произойти по многим причинам; иногда пользователь отправляет форму двойным щелчком, или он после отправки решает исправить содержимое поста и нажимает кнопку браузера "Назад". А иногда это - намеренные действия злоумышленников. Понятно, что дублирование отправки может привести ко многим проблемам. Поэтому нам нужно принимать эффективные меры для его предотвращения. -Решением этой задачи является добавление в форму скрытого поля с уникальным токеном и проверка этого токена перед перед обработкой введенных данных. А если для отправки формы Вы используете Ajax, можно после того, как данные отправлены, сделать кнопку отправки неактивной. +Решением этой задачи является добавление в форму скрытого поля с уникальным токеном и проверка этого токена перед обработкой введенных данных. А если для отправки формы Вы используете Ajax, можно после того, как данные отправлены, сделать кнопку отправки неактивной. Давайте усовершенствуем пример из раздела 4.2: - +```html Футбол Баскетбол Теннис @@ -13,35 +13,35 @@ Пароль: - +``` Для того, чтобы сгенерировать токен, мы используем хэш MD5 (временная отметка), и добавляем его как в скрытое поле формы ввода данных на стороне клиента, так и в сессионный куки на стороне сервера (см. Раздел 6). Мы можем использовать этот токен для того, чтобы проверить, отправлялись ли уже данные с этой формы: +```Go +func login(w http.ResponseWriter, r *http.Request) { + fmt.Println("method:", r.Method) // получаем метод запроса + if r.Method == "GET" { + crutime := time.Now().Unix() + h := md5.New() + io.WriteString(h, strconv.FormatInt(crutime, 10)) + token := fmt.Sprintf("%x", h.Sum(nil)) - func login(w http.ResponseWriter, r *http.Request) { - fmt.Println("method:", r.Method) // получаем метод запроса - if r.Method == "GET" { - crutime := time.Now().Unix() - h := md5.New() - io.WriteString(h, strconv.FormatInt(crutime, 10)) - token := fmt.Sprintf("%x", h.Sum(nil)) - - t, _ := template.ParseFiles("login.gtpl") - t.Execute(w, token) - } else { - // запрос данных о входе - r.ParseForm() - token := r.Form.Get("token") - if token != "" { - // проверяем валидность токена - } else { - // если нет токена, возвращаем ошибку - } - fmt.Println("username length:", len(r.Form["username"][0])) - fmt.Println("username:", template.HTMLEscapeString(r.Form.Get("username"))) // печатаем на стороне сервера - fmt.Println("password:", template.HTMLEscapeString(r.Form.Get("password"))) - template.HTMLEscape(w, []byte(r.Form.Get("username"))) // отвечаем клиенту - } + t, _ := template.ParseFiles("login.gtpl") + t.Execute(w, token) + } else { + // запрос данных о входе + r.ParseForm() + token := r.Form.Get("token") + if token != "" { + // проверяем валидность токена + } else { + // если нет токена, возвращаем ошибку + } + fmt.Println("username length:", len(r.Form["username"][0])) + fmt.Println("username:", template.HTMLEscapeString(r.Form.Get("username"))) // печатаем на стороне сервера + fmt.Println("password:", template.HTMLEscapeString(r.Form.Get("password"))) + template.HTMLEscape(w, []byte(r.Form.Get("username"))) // отвечаем клиенту } - +} +``` ![](images/4.4.token.png?raw=true) Рисунок 4.4 Содержимое браузера после добавления токена