Чем горилла / контекст отличается от гориллы / сессий?

Я получаю сессии из PHP, которые я использовал

<?php
session_start();
$_SESSION["key"] = "val";
echo $_SESSION["key"];
?>

Установите один или несколько ключей и их значения на стороне сервера и сможете получать или перезаписывать их до истечения сеанса.

То же самое с гориллой / сессиями

var(
    sessionStore  *sessions.CookieStore
    sessionSecret []byte = make([]byte, 64)
    session       *sessions.Session
)

func init(){
    sessionSecret = []byte("12345678901234567890123456789012")
    sessionStore = sessions.NewCookieStore(sessionSecret)
    session = sessions.NewSession(sessionStore, "session_name")
}

func SetSessionHandler(w http.ResponseWriter, r *http.Request) {
    session, _ = sessionStore.Get(r, "session_name")
    session.Values["key"] = "val"
    session.Save(r, w)
}

func GetSessionHandler(w http.ResponseWriter, r *http.Request) {
    session, _ = sessionStore.Get(r, "session_name")
    fmt.FPrintln(session.Values["key"])
}

Теперь я не понимаю, в чем смысл гориллы / контекста. Я знаю, что такое контекст, но... я не знаю, как он вписывается в общую картину. Он говорит, что он привязан к текущему запросу. Другой вопрос здесь о stackru сказал, что "достаточно просто использовать gorilla / context" в контексте написания промежуточного программного обеспечения для каждого обработчика.

Но если это связано с запросом... ошибка... синтаксическая ошибка, не вычисляется. Если утка плавает на воде, то ведьмы сделаны из дерева. И поскольку утки также плавают на воде, если ее вес такой же, как у утки, она должна быть ведьмой. Или что-то типа того;)

И как это может быть полезно в качестве "менеджера" промежуточного программного обеспечения, когда оно привязано к запросу, я не могу установить его глобально. Не могли бы вы показать пример использования гориллы / сессий с гориллой / контекстом?

2 ответа

Решение

Как человек, который задал этот другой вопрос:

  • горилла / контекст позволяет хранить данные в запросе. Если у вас есть промежуточное программное обеспечение, которое выполняет предварительную обработку запроса до принятия решения о продолжении (например, anti-CSRF), вы можете сохранить токен в запросе, чтобы ваш обработчик мог передать его шаблону. Горилла / контекстная документация хорошо объясняют это:

... маршрутизатор может устанавливать переменные, извлеченные из URL, и более поздние обработчики приложений могут получать доступ к этим значениям, или он может использоваться для хранения значений сеансов, которые будут сохранены в конце запроса. Есть несколько других общих применений.

  • Возможно, вы также захотите сохранить данные в сеансе: здесь, вероятно, будут храниться сообщения об ошибках из отправленных форм, идентификатор пользователя или "каноническая" версия токена CSRF для этого посетителя. Если вы попытаетесь сохранить сообщение об ошибке в контексте запроса, а затем перенаправить пользователя, вы потеряете его (это новый запрос).

Так почему бы вам использовать контекст над сессиями? Он легче и позволяет вам отделять части вашего приложения (часто промежуточное ПО HTTP!) Друг от друга.

Пример:

  1. Запрос приходит
  2. Промежуточное программное обеспечение CSRF проверяет сеанс на наличие токена CSRF. Не существует, поэтому он устанавливает один.
  3. Он также передает этот новый токен (через контекст запроса!) Обработчику, который отображает вашу форму, чтобы он мог отобразить его в шаблоне (в противном случае вам придется снова извлечь токен из сеанса, что напрасно тратит усилия)
  4. Запрос выполнен.
  5. Новый запрос на отправку формы
  6. Токен все еще сохраняется в сеансе, поэтому мы можем сравнить его с отправленным токеном из формы.
  7. Если это подтвердится, мы приступаем к обработке формы
  8. Если нет, мы можем сохранить ошибку в сеансе (флэш-сообщение; т.е. сообщение, которое стерто после чтения) и перенаправить.
  9. Это перенаправление является новым запросом, и поэтому мы не можем передать сообщение об ошибке через контекст запроса здесь.

Пример.

Я пишу это программное обеспечение для нескольких форумов. Теперь у меня есть маршрутизатор gorilla/mux, который обслуживает другой контент для основного домена, и другой маршрутизатор, который обслуживает другой контент, отфильтрованный по subdomain.domain.tld.

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

Таким образом, преимущество контекста состоит в том, что код остается СУХИМЫМ.

Как писал Элихрар, его пример токена CSRF. Если вы знаете, что вам нужно проверять токен CSRF при каждом запросе - не дублируйте эту проверку в каждом обработчике, который должен это делать, вместо этого напишите контекстную оболочку ( / http.Handler) и делайте это для каждого запроса.

Другие вопросы по тегам