Из документации по контексту, чтобы установить значение в контексте, вам просто нужно использовать WithValue .
Чтобы дать вам представление, простейшим примером будет:
package main
import (
"fmt"
"context"
)
func main() {
const key = "myKey"
ctx := context.Background()
ctx := context.WithValue(ctx, key, "someVal")
v, ok := ctx.Value(key).(string)
if !ok {
fmt.Println("key does not exist in the context")
return
}
fmt.Printf("found %v", v)
}
Теперь, следуя примеру, довольно просто установить новое значение в контексте.Когда мы говорим о r.Context()
, исходящий из него контекст был предварительно установлен в запросе *http.Request
с использованием WithContext .Простой пример:
package main
import (
"http"
"context"
)
func main() {
req, err := http.NewRequest(
http.MethodGet,
"/someEdp",
nil,
)
if err != nil {
fmt.Println(err)
return
}
ctx := context.Background()
ctx := context.WithValue(ctx, "auth-token", "mySecretToken")
req = req.WithContext(ctx)
// Do the request
}
И прочитать его в вашем обработчике было бы так же просто, как:
func (rs *appResource) login(w http.ResponseWriter, r *http.Request) {
...
ctx := r.Context()
v, ok := ctx.Value("auth-token").(string)
if !ok {
fmt.Println("ups")
return
}
fmt.Printf("found %v", v)
// Do something
}
Теперь, если вы хотите использовать этот механизм для безопасного хранения ипрочитайте токен авторизации в контексте, я предлагаю вам взглянуть на эту статью о ключах контекста , написанных @Mat Ryer.
По сути, любой, кто «перехватывает» ваш запрос, можетпотенциально прочитайте токен авторизации из вашего запроса, потому что вы используете строку в качестве ключа.
Вместо этого вы должны определить свой закрытый контекстный ключ, который позволит вам установить / прочитать токен авторизации из контекста.
package main
import (
"fmt"
"context"
)
type contextKey string
var contextKeyAuthtoken = contextKey("auth-token")
func setToken(ctx context.Context, token string) context.Context {
return context.WithValue(ctx, contextKeyAuthtoken, token)
}
func getToken(ctx context.Context) (string, bool) {
tokenStr, ok := ctx.Value(contextKeyAuthtoken).(string)
return tokenStr, ok
}
func main() {
ctx := context.Background()
ctx = setToken(ctx, "someToken")
t, ok := getToken(ctx)
if !ok {
fmt.Println("unauthorized")
return
}
fmt.Printf("authorized with token %v", t)
}
Вот игровая площадка , которую я установил для приведенного выше фрагмента.
Итак, вы бы использовали getToken
в получателе запроса (обработчике вашего получателя) & setToken
в другом сервисе (?) Или другом логическом компоненте вашего сервиса.
Таким образом вы и только вы сможете прочитать из контекста свой токен авторизации и позволить пользователю делатьчто-то или нет.