Чем горилла / контекст отличается от гориллы / сессий?
Я получаю сессии из 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!) Друг от друга.
Пример:
- Запрос приходит
- Промежуточное программное обеспечение CSRF проверяет сеанс на наличие токена CSRF. Не существует, поэтому он устанавливает один.
- Он также передает этот новый токен (через контекст запроса!) Обработчику, который отображает вашу форму, чтобы он мог отобразить его в шаблоне (в противном случае вам придется снова извлечь токен из сеанса, что напрасно тратит усилия)
- Запрос выполнен.
- Новый запрос на отправку формы
- Токен все еще сохраняется в сеансе, поэтому мы можем сравнить его с отправленным токеном из формы.
- Если это подтвердится, мы приступаем к обработке формы
- Если нет, мы можем сохранить ошибку в сеансе (флэш-сообщение; т.е. сообщение, которое стерто после чтения) и перенаправить.
- Это перенаправление является новым запросом, и поэтому мы не можем передать сообщение об ошибке через контекст запроса здесь.
Пример.
Я пишу это программное обеспечение для нескольких форумов. Теперь у меня есть маршрутизатор gorilla/mux, который обслуживает другой контент для основного домена, и другой маршрутизатор, который обслуживает другой контент, отфильтрованный по subdomain.domain.tld.
Здесь очень полезен контекст, иначе вы будете повторяться снова и снова. Поэтому, если я знаю, что для маршрутизатора субдомена каждый запрос будет выполнять строковые операции, чтобы узнать имя субдомена и проверить, существует ли оно в базе данных, я мог бы просто сделать это здесь (в контексте) для каждого запроса, а затем сохранить имя субдомена в контекстная переменная. И точно так же, если установлен форумный слаг или форумный слаг или потоковый слаг, передайте его обработчику, сохраните обработку, которая должна быть выполнена в "контексте", и в ваших обработчиках будет меньше кода.
Таким образом, преимущество контекста состоит в том, что код остается СУХИМЫМ.
Как писал Элихрар, его пример токена CSRF. Если вы знаете, что вам нужно проверять токен CSRF при каждом запросе - не дублируйте эту проверку в каждом обработчике, который должен это делать, вместо этого напишите контекстную оболочку ( / http.Handler) и делайте это для каждого запроса.