В каком месте HTTP ответа указывается ссылка для перенаправления пользователя
Что проверяют
Базовое знание протокола и то, как оно ложится на net/http. Ответ «в заголовке Location» интервьюер ждёт сразу, а следом спрашивает, чем 301 отличается от 307 и как сделать редирект в Go, не наступив на порядок записи ответа.
Как отвечать
Адрес для перенаправления передаётся в заголовке Location, а код состояния из группы 3xx говорит клиенту, как с ним поступить:
- 301 и 302: постоянный и временный редирект. Исторически браузеры при таком ответе на
POSTповторяют запрос уже методомGET, и спецификация это допускает; - 303 See Other: явное указание сходить за результатом через
GET, классика для паттерна Post/Redirect/Get после отправки формы; - 307 и 308: временный и постоянный редирект с сохранением метода и тела запроса;
- кэш: 301 и 308 браузер может закэшировать надолго, поэтому для временного переезда их не используют.
Location может содержать и относительный адрес, RFC 9110 это разрешает. Тот же заголовок встречается в ответе 201 Created, но там он указывает на созданный ресурс, а не перенаправляет.
В Go на сервере это http.Redirect(w, r, "/login", http.StatusSeeOther): функция ставит Location, пишет статус и для GET добавляет короткое HTML-тело. Заголовки задаются до WriteHeader или первой записи тела, после этого их изменения игнорируются. На клиенте http.Client по умолчанию проходит до 10 редиректов. Поведение меняется через поле CheckRedirect, а если вернуть из него http.ErrUseLastResponse, клиент отдаст сам ответ 3xx, не переходя по ссылке.
Где спотыкаются
Забывают return после http.Redirect. Обработчик продолжает работу, и если дальше вызвать http.Error или ещё раз WriteHeader, в логе появится http: superfluous response.WriteHeader call, а клиент получит мусор в теле.
Ставят 301 на временное перенаправление. Браузеры запоминают его, и когда адрес вернётся обратно, часть пользователей ещё долго будет уходить по старому редиректу.
Берут адрес для редиректа из параметра запроса без проверки. Так появляется open redirect: ссылка на ваш домен уводит на фишинговый сайт. Разрешайте только относительные пути или адреса из белого списка.