in appengine/go11x/pubsub/authenicated_push/main.go [75:140]
func (a *app) receiveMessagesHandler(w http.ResponseWriter, r *http.Request) {
if r.Method != "POST" {
http.Error(w, http.StatusText(http.StatusMethodNotAllowed), http.StatusMethodNotAllowed)
return
}
// Verify that the request originates from the application.
// a.pubsubVerificationToken = os.Getenv("PUBSUB_VERIFICATION_TOKEN")
if token, ok := r.URL.Query()["token"]; !ok || len(token) != 1 || token[0] != a.pubsubVerificationToken {
http.Error(w, "Bad token", http.StatusBadRequest)
return
}
// Get the Cloud Pub/Sub-generated JWT in the "Authorization" header.
authHeader := r.Header.Get("Authorization")
if authHeader == "" || len(strings.Split(authHeader, " ")) != 2 {
http.Error(w, "Missing Authorization header", http.StatusBadRequest)
return
}
token := strings.Split(authHeader, " ")[1]
// Verify and decode the JWT.
// If you don't need to control the HTTP client used you can use the
// convenience method idtoken.Validate instead of creating a Validator.
v, err := idtoken.NewValidator(r.Context(), option.WithHTTPClient(a.defaultHTTPClient))
if err != nil {
http.Error(w, "Unable to create Validator", http.StatusBadRequest)
return
}
// Please change http://example.com to match with the value you are
// providing while creating the subscription.
payload, err := v.Validate(r.Context(), token, "http://example.com")
if err != nil {
http.Error(w, fmt.Sprintf("Invalid Token: %v", err), http.StatusBadRequest)
return
}
if payload.Issuer != "accounts.google.com" && payload.Issuer != "https://accounts.google.com" {
http.Error(w, "Wrong Issuer", http.StatusBadRequest)
return
}
// IMPORTANT: you should validate claim details not covered by signature
// and audience verification above, including:
// - Ensure that `payload.Claims["email"]` is equal to the expected service
// account set up in the push subscription settings.
// - Ensure that `payload.Claims["email_verified"]` is set to true.
if payload.Claims["email"] != "test-service-account-email@example.com" || payload.Claims["email_verified"] != true {
http.Error(w, "Unexpected email identity", http.StatusBadRequest)
return
}
var pr pushRequest
if err := json.NewDecoder(r.Body).Decode(&pr); err != nil {
http.Error(w, fmt.Sprintf("Could not decode body: %v", err), http.StatusBadRequest)
return
}
a.messagesMu.Lock()
defer a.messagesMu.Unlock()
// Limit to ten.
a.messages = append(a.messages, pr.Message.Data)
if len(a.messages) > maxMessages {
a.messages = a.messages[len(a.messages)-maxMessages:]
}
fmt.Fprint(w, "OK")
}