func RequireApiKey(handler http.Handler) http.HandlerFunc { return func(w http.ResponseWriter, r *http.Request) { apiKeyHeader := r.Header["Api-Key"] if len(apiKeyHeader) != 1 { w.Header().Set("Content-Type", "text/plain") w.WriteHeader(http.StatusUnauthorized) w.Write([]byte("No API-KEY header!")) ctx.Clear(r) return } apiKey := apiKeyHeader[0] user, err := models.GetUserByApiKey(apiKey) if err != nil { w.Header().Set("Content-Type", "text/plain") w.WriteHeader(http.StatusUnauthorized) w.Write([]byte("Api Key is incorrect!")) ctx.Clear(r) return } ctx.Set(r, "user", user) handler.ServeHTTP(w, r) ctx.Clear(r) } }
func createContext(next http.Handler) http.Handler { return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { context.Set(r, k, Context{}) next.ServeHTTP(w, r) context.Clear(r) // clears after handling everything. }) }
func httpLogger(r *http.Request, created time.Time, status, bytes int) { //fmt.Println(httpxtra.ApacheCommonLog(r, created, status, bytes)) var ( s, ip, msg string err error ) if r.TLS == nil { s = "HTTP" } else { s = "HTTPS" } if ip, _, err = net.SplitHostPort(r.RemoteAddr); err != nil { ip = r.RemoteAddr } if tmp := context.Get(r, "log"); tmp != nil { msg = fmt.Sprintf(" (%s)", tmp) context.Clear(r) } log.Printf("%s %d %s %q (%s) :: %d bytes in %s%s", s, status, r.Method, r.URL.Path, ip, bytes, time.Since(created), msg, ) if collectStats { protocolCount.Add(s, 1) statusCount.Add(strconv.Itoa(status), 1) } }
func (g *Req) finished(appStats AppStats) { context.Clear(g.R) // Cleanup gorilla stash reqDuration := time.Since(g.startTime) g.app.WriteAccessLog(g, reqDuration) // Don't run time-based code for websockets if g.WS != nil { return } codeStatsKey := fmt.Sprintf("http_status.%d", g.W.code) g.app.Stats.Inc(codeStatsKey, 1) slowReqSecs, _ := g.Cfg.GetFloat32("gop", "slow_req_secs", 10) if reqDuration.Seconds() > float64(slowReqSecs) && !g.CanBeSlow { g.Errorf("Slow request [%s] took %s", g.R.URL.Host, reqDuration) } else { g.Debug("Request took %s", reqDuration) } // Tidy up request finalistion (requestMaker, req.finish() method, app.requestFinished()) restartReqs, _ := g.Cfg.GetInt("gop", "max_requests", 0) if restartReqs > 0 && appStats.totalReqs > restartReqs { g.Errorf("Graceful restart after max_requests: %d", restartReqs) g.app.StartGracefulRestart("Max requests reached") } gcEveryReqs, _ := g.Cfg.GetInt("gop", "gc_requests", 0) if gcEveryReqs > 0 && appStats.totalReqs%gcEveryReqs == 0 { g.Info("Forcing GC after %d reqs", appStats.totalReqs) runtime.GC() } }
func TestUserSession(t *testing.T) { userStore := store{kUserId} sessionStore := newSessionStoreWithUserId(kSessionId, kUserId) r := requestWithCookie(kSessionCookieName, kSessionId) us, err := session_util.NewUserSession( sessionStore, r, kSessionCookieName, func(s *sessions.Session) session_util.UserSession { return newUserSession(s) }, userStore, errNoSuchId) if err != nil { t.Fatalf("An error happened getting userSession: %v", err) } defer context.Clear(r) myUserSession := us.(*userSession) if output := myUserSession.User; *output != kUserId { t.Errorf("Expected %v, got %v", kUserId, *output) } if myUserSession != session_util.GetUserSession(r) { t.Error("User session not stored with request.") } }
func logMsg(r *http.Request) string { if msg := context.Get(r, "log"); msg != nil { defer context.Clear(r) return fmt.Sprintf(" (%s)", msg) } return "" }
func InitHandlers() { initCodeBaseDir() // Register datatypes such that it can be saved in the session. gob.Register(SessionUserKey(0)) gob.Register(&User{}) // Initialize XSRF token key. xsrfKey = "My personal very secure XSRF token key" sessKey := []byte("secure-key-234002395432-wsasjasfsfsfsaa-234002395432-wsasjasfsfsfsaa-234002395432-wsasjasfsfsfsaa") // Create a session cookie store. cookieStore = sessions.NewCookieStore( sessKey[:64], sessKey[:32], ) cookieStore.Options = &sessions.Options{ MaxAge: maxSessionIDAge, // Session valid for 30 Minutes. HttpOnly: true, } // Create identity toolkit client. c := &gitkit.Config{ ServerAPIKey: getConfig(siteName, "serverAPIKey"), ClientID: getConfig(siteName, "clientID"), WidgetURL: WidgetSigninAuthorizedRedirectURL, } // Service account and private key are not required in GAE Prod. // GAE App Identity API is used to identify the app. if appengine.IsDevAppServer() { c.ServiceAccount = getConfig(siteName, "serviceAccount") c.PEMKeyPath = privateKeyPath } var err error gitkitClient, err = gitkit.New(c) if err != nil { log.Fatal(err) } // The gorilla sessions use gorilla request context ClearHandler := func(fc http.HandlerFunc) http.Handler { return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { defer gorillaContext.Clear(r) fc(w, r) }) } http.Handle(homeURL, ClearHandler(handleHome)) http.Handle(WidgetSigninAuthorizedRedirectURL, ClearHandler(handleWidget)) http.Handle(signOutURL, ClearHandler(handleSignOut)) http.Handle(signinLandingDefaultURL, ClearHandler(handleSigninSuccessLanding)) http.Handle(signoutLandingDefaultURL, ClearHandler(handleSignOutLanding)) http.HandleFunc(accountChooserBrandingURL, accountChooserBranding) }
func AuthHttpInterceptor(router http.Handler) http.Handler { return http.HandlerFunc(func(w http.ResponseWriter, req *http.Request) { startTime := time.Now() if !Auth(w, req) { http.Error(w, "Failed authentication", 401) return } router.ServeHTTP(w, req) finishTime := time.Now() elapsedTime := finishTime.Sub(startTime) switch req.Method { case "GET": // We may not always want to StatusOK, but for the sake of // this example we will common.LogAccess(w, req, elapsedTime) case "POST": // here we might use http.StatusCreated } context.Clear(req) }) }
func getDB(r *http.Request) *mgo.Session { if session := context.Get(r, "db"); session != nil { context.Clear(r) return session.(*mgo.Session) } return nil }
func (s *Sessions) ServeHTTP(w http.ResponseWriter, r *http.Request, next http.HandlerFunc) { authorizations := strings.Split(r.Header.Get("Authorization"), ",") var authToken string for _, v := range authorizations { fmt.Sscanf(strings.Trim(v, " "), "AuthToken authToken=%s", &authToken) if authToken != "" { break } } if authToken == "" { cookie, err := r.Cookie("authToken") if err == nil { authToken = cookie.Value } } if authToken != "" { session, _ := s.interactor.CurrentSessionFromToken(authToken) if session != nil { context.Set(r, "currentSession", *session) } } next(w, r) context.Clear(r) }
func (router *Router) ServeHTTP(w http.ResponseWriter, r *http.Request) { defer context.Clear(r) u4, err := gouuid.NewV4() if err != nil { log.Panic(err) } uuidToken := u4.String() context.Set(r, uuidKey, uuidToken) defer bugsnag.OnCapturePanic(r, func(event bugsnag.EventDescriber) { event.WithMetaData("request", "uuid", uuidToken) }) log.Println(uuidToken, "Start", r.Method, r.URL, "for", parseRemoteAddr(r)) w.Header().Set("Cache-Control", "no-cache, private, no-store, must-revalidate, max-stale=0, post-check=0, pre-check=0") if origin, ok := isWhiteListedCorsOrigin(r); ok { w.Header().Set("Access-Control-Allow-Origin", origin) w.Header().Set("Access-Control-Allow-Headers", "Content-Type, Depth, User-Agent, X-File-Size, X-Requested-With, If-Modified-Since, X-File-Name, Cache-Control, Authorization, Accept, Accept-Encoding, Accept-Language, Access-Control-Request-Headers, Access-Control-Request-Method, Connection, Host, Origin, User-Agent") w.Header().Set("Access-Control-Allow-Methods", "GET, OPTIONS, PUT, POST, DELETE") w.Header().Set("Access-Control-Allow-Credentials", "true") w.Header().Set("Access-Control-Max-Age", "1728000") } if r.Method == "OPTIONS" { w.Header().Set("Content-Length", "0") w.WriteHeader(http.StatusOK) return } router.Routes.ServeHTTP(w, r) }
func (env *Env) SpotifyGetKeys(w http.ResponseWriter, r *http.Request) { authClient = setup() token, err := pullToken(r, env) if err != nil { common.DisplayAppError(w, err, "error with pulling token, may need to re-auth", 500) return } //have our SpotifyClient here: client := authClient.FinalAuth(token) var keys IncomingKeys if r.Method == "POST" { err := json.NewDecoder(r.Body).Decode(&keys) if err != nil { common.DisplayAppError(w, err, "Invalid Keys data", 500) return } } notesChosen := keys.Data.Keys songs, _ := GetSongsByKey(notesChosen, client) reqcontext.Clear(r) if j, err := json.Marshal(SongKeysResource{Data: songs}); err != nil { fmt.Println("error in controllers.SpotifyGetKeys json.Marshal") return } else { w.Header().Set("Content-Type", "application/json") w.WriteHeader(http.StatusOK) w.Write(j) } }
func Test_WillieSessions(t *testing.T) { r := require.New(t) w := willie.New(http.HandlerFunc(func(res http.ResponseWriter, req *http.Request) { defer context.Clear(req) sess, _ := Store.Get(req, "my-session") t := sess.Values["foo"] fmt.Printf("t: %s\n", t) if t != nil { res.WriteHeader(200) fmt.Fprint(res, t) } else { sess.Values["foo"] = "bar" sess.Save(req, res) res.WriteHeader(201) fmt.Fprint(res, "setting session") } })) res := w.Get("/", nil) r.Equal(201, res.Code) r.Equal("setting session", res.Body.String()) res = w.Get("/", nil) r.Equal(200, res.Code) r.Equal("bar", res.Body.String()) }
func (h Handle) ServeHTTP(w http.ResponseWriter, r *http.Request) { requestLog.Info("%v %v", r.Method, r.RequestURI) for _, initializer := range initializers { initializer(r) } buffer := new(httpbuf.Buffer) err := h(buffer, r) if err != nil { fmt.Println(err) if webErr, ok := err.(WebError); ok { http.Error(w, webErr.Message, webErr.Code) } else { http.Error(w, err.Error(), http.StatusInternalServerError) } } err = Session(r).Save(r, buffer) context.Clear(r) buffer.Apply(w) }
// HandlerSocket handles inbound websocket connections only at /publish func HandlerSocket(w http.ResponseWriter, r *http.Request) { clientName, _ := context.Get(r, "ClientName").(string) context.Clear(r) // Upgrade the request socket, err := upgrader.Upgrade(w, r, nil) if err != nil { panic(err) } defer socket.Close() // Create a Connection instance c := hub.NewConnection(socket.RemoteAddr().String(), clientName) hub.Manager.RegisterConnection(&c) defer hub.Manager.Cleanup(&c) // Handle inbound publish messages for { m := message.SocketMessage{ Action: "publish", CreatedAt: time.Now().UTC(), } err = socket.ReadJSON(&m) if err != nil { break } hub.Manager.Publish(m) } }
// ServeHTTP will store the request details in the analytics store if necessary and proxy the request to it's // final destination, this is invoked by the ProxyHandler or right at the start of a request chain if the URL // Spec states the path is Ignored func (s SuccessHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) { // Make sure we get the correct target URL if s.Spec.APIDefinition.Proxy.StripListenPath { r.URL.Path = strings.Replace(r.URL.Path, s.Spec.Proxy.ListenPath, "", 1) } if config.EnableAnalytics { t := time.Now() // Track the key ID if it exists authHeaderValue := context.Get(r, AuthHeaderValue) keyName := "" if authHeaderValue != nil { keyName = authHeaderValue.(string) } // Track version data version := s.Spec.getVersionFromRequest(r) if version == "" { version = "Non Versioned" } // If OAuth, we need to grab it from the session, which may or may not exist OauthClientID := "" thisSessionState := context.Get(r, SessionData) if thisSessionState != nil { OauthClientID = thisSessionState.(SessionState).OauthClientID } thisRecord := AnalyticsRecord{ r.Method, r.URL.Path, r.ContentLength, r.Header.Get("User-Agent"), t.Day(), t.Month(), t.Year(), t.Hour(), 200, keyName, t, version, s.Spec.APIDefinition.Name, s.Spec.APIDefinition.APIID, s.Spec.APIDefinition.OrgID, OauthClientID} go analytics.RecordHit(thisRecord) } s.Proxy.ServeHTTP(w, r) if doMemoryProfile { pprof.WriteHeapProfile(profileFile) } context.Clear(r) }
// ServeHTTP dispatches the handler registered in the matched route. // // When there is a match, the route variables can be retrieved calling // mux.Vars(request). func (r *Router) ServeHTTP(w http.ResponseWriter, req *http.Request) { // Clean path to canonical form and redirect. if p := cleanPath(req.URL.Path); p != req.URL.Path { w.Header().Set("Location", p) w.WriteHeader(http.StatusMovedPermanently) return } var match RouteMatch var handler http.Handler if r.Match(req, &match) { handler = match.Handler setVars(req, match.Vars) setCurrentRoute(req, match.Route) } if handler == nil { if r.NotFoundHandler == nil { r.NotFoundHandler = http.NotFoundHandler() } handler = r.NotFoundHandler } if !r.KeepContext { defer context.Clear(req) } handler.ServeHTTP(w, req) }
// HandleError is the actual error handler and will store the error details in analytics if analytics processing is enabled. func (e ErrorHandler) HandleError(w http.ResponseWriter, r *http.Request, err string, errCode int) { if config.EnableAnalytics { t := time.Now() // Track the key ID if it exists authHeaderValue := context.Get(r, AuthHeaderValue) keyName := "" if authHeaderValue != nil { keyName = authHeaderValue.(string) } version := e.Spec.getVersionFromRequest(r) if version == "" { version = "Non Versioned" } if e.TykMiddleware.Spec.APIDefinition.Proxy.StripListenPath { r.URL.Path = strings.Replace(r.URL.Path, e.TykMiddleware.Spec.Proxy.ListenPath, "", 1) } OauthClientID := "" thisSessionState := context.Get(r, SessionData) if thisSessionState != nil { OauthClientID = thisSessionState.(SessionState).OauthClientID } thisRecord := AnalyticsRecord{ r.Method, r.URL.Path, r.ContentLength, r.Header.Get("User-Agent"), t.Day(), t.Month(), t.Year(), t.Hour(), errCode, keyName, t, version, e.Spec.APIDefinition.Name, e.Spec.APIDefinition.APIID, e.Spec.APIDefinition.OrgID, OauthClientID} go analytics.RecordHit(thisRecord) } w.Header().Add("Content-Type", "application/json") w.Header().Add("X-Generator", "tyk.io") log.Debug("Returning error header") w.WriteHeader(errCode) thisError := APIError{fmt.Sprintf("%s", err)} templates.ExecuteTemplate(w, "error.json", &thisError) if doMemoryProfile { pprof.WriteHeapProfile(profileFile) } // Clean up context.Clear(r) }
// AutoLogin 用于 echo 框架的自动登录和通过 cookie 获取用户信息 func AutoLogin() echo.MiddlewareFunc { return func(next echo.HandlerFunc) echo.HandlerFunc { return func(ctx echo.Context) error { // github.com/gorilla/sessions 要求必须 Clear defer context.Clear(Request(ctx)) session := GetCookieSession(ctx) username, ok := session.Values["username"] if ok { if db.MasterDB != nil { // TODO: 考虑缓存,或延迟查询,避免每次都查询 user := logic.DefaultUser.FindCurrentUser(ctx, username) if user.Uid != 0 { ctx.Set("user", user) } } } if err := next(ctx); err != nil { return err } return nil } } }
func newRouter(ctx *Context, next http.Handler) http.Handler { if ctx.router == nil { ctx.router = DefaultRouter(ctx.spec, ctx.api) } isRoot := ctx.spec.BasePath() == "" || ctx.spec.BasePath() == "/" return http.HandlerFunc(func(rw http.ResponseWriter, r *http.Request) { defer context.Clear(r) // use context to lookup routes if isRoot { if _, ok := ctx.RouteInfo(r); ok { next.ServeHTTP(rw, r) return } } else { if p := strings.TrimPrefix(r.URL.Path, ctx.spec.BasePath()); len(p) < len(r.URL.Path) { r.URL.Path = p if _, ok := ctx.RouteInfo(r); ok { next.ServeHTTP(rw, r) return } } } // Not found, check if it exists in the other methods first if others := ctx.AllowedMethods(r); len(others) > 0 { ctx.Respond(rw, r, ctx.spec.RequiredProduces(), nil, errors.MethodNotAllowed(r.Method, others)) return } ctx.Respond(rw, r, ctx.spec.RequiredProduces(), nil, errors.NotFound("path %s was not found", r.URL.Path)) }) }
// GetContext wraps each request in a function which fills in the context for a given request. // This includes setting the User and Session keys and values as necessary for use in later functions. func GetContext(handler http.Handler) http.HandlerFunc { // Set the context here return func(w http.ResponseWriter, r *http.Request) { // Parse the request form err := r.ParseForm() if err != nil { http.Error(w, "Error parsing request", http.StatusInternalServerError) } // Set the context appropriately here. // Set the session session, _ := auth.Store.Get(r, "gophish") // Put the session in the context so that ctx.Set(r, "session", session) if id, ok := session.Values["id"]; ok { u, err := models.GetUser(id.(int64)) if err != nil { ctx.Set(r, "user", nil) } else { ctx.Set(r, "user", u) } } else { ctx.Set(r, "user", nil) } handler.ServeHTTP(w, r) // Remove context contents ctx.Clear(r) } }
// logHandler logs http requests. func logHandler(f http.Handler) http.Handler { empty := "" return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { resp := responseWriter{w, http.StatusOK, 0} start := time.Now() f.ServeHTTP(&resp, r) elapsed := time.Since(start) extra := context.Get(r, "log") if extra != nil { defer context.Clear(r) } else { extra = empty } log.Printf("%q %d %q %q %s %q %db in %s %q", r.Proto, resp.status, r.Method, r.URL.Path, remoteIP(r), r.Header.Get("User-Agent"), resp.bytes, elapsed, extra, ) }) }
// ServeHTTP dispatches the handler registered in the matched route. // // When there is a match, the route variables can be retrieved calling // mux.Vars(request). func (r *Router) ServeHTTP(w http.ResponseWriter, req *http.Request) { // Clean path to canonical form and redirect. if p := cleanPath(req.URL.Path); p != req.URL.Path { // Added 3 lines (Philip Schlump) - It was droping the query string and #whatever from query. // This matches with fix in go 1.2 r.c. 4 for same problem. Go Issue: // http://code.google.com/p/go/issues/detail?id=5252 url := *req.URL url.Path = p p = url.String() w.Header().Set("Location", p) w.WriteHeader(http.StatusMovedPermanently) return } var match RouteMatch var handler http.Handler if r.Match(req, &match) { handler = match.Handler setVars(req, match.Vars) setCurrentRoute(req, match.Route) } if handler == nil { handler = r.NotFoundHandler if handler == nil { handler = http.NotFoundHandler() } } if !r.KeepContext { defer context.Clear(req) } handler.ServeHTTP(w, req) }
func logout(res http.ResponseWriter, req *http.Request) { defer context.Clear(req) session, _ := store.Get(req, "session") session.Values["loggedin"] = "false" session.Save(req, res) http.Redirect(res, req, "/login", 302) }
// restrictedHandler enforce authentication by validating the JWT token func restrictedHandler(next http.Handler) http.Handler { return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { token, err := jwt.ParseFromRequest(r, func(t *jwt.Token) (interface{}, error) { return pubKeyPEM, nil }) if token != nil && err == nil { if token.Valid { setTokenIntoContext(r, token) authorized := hasPermission(token, r) if !authorized { http.Error(w, "", http.StatusForbidden) return } next.ServeHTTP(w, r) context.Clear(r) } else { http.Error(w, err.Error(), http.StatusUnauthorized) return } } else { http.Error(w, err.Error(), http.StatusUnauthorized) return } }) }
// restrictedHandler enforce authentication by validating the JWT token func restrictedHandler(next http.Handler) http.Handler { return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { token, err := jwt.ParseFromRequest(r, func(t *jwt.Token) (interface{}, error) { if _, ok := t.Method.(*jwt.SigningMethodRSA); !ok { return nil, fmt.Errorf("Unexpected signing method: %v", t.Header["alg"]) } return publicKey, nil }) if token != nil && err == nil { if token.Valid { setTokenIntoContext(r, token) authorized := hasPermission(token, r) if !authorized { http.Error(w, "", http.StatusForbidden) return } next.ServeHTTP(w, r) context.Clear(r) } else { http.Error(w, err.Error(), http.StatusUnauthorized) return } } else { http.Error(w, err.Error(), http.StatusUnauthorized) return } }) }
//Middleware to create the logging context func (a *App) LoggingContext(w http.ResponseWriter, r *http.Request, next http.HandlerFunc) { session, err := Store.Get(r, "session-key") if err != nil { logger.Get().Error("Error Getting the session. error: %v", err) w.WriteHeader(http.StatusInternalServerError) return } var username string if val, ok := session.Values["username"]; ok { username = val.(string) } reqId, err := uuid.New() if err != nil { logger.Get().Error("Error Creating the RequestId. error: %v", err) w.WriteHeader(http.StatusInternalServerError) return } loggingContext := fmt.Sprintf("%v:%v", username, reqId.String()) context.Set(r, LoggingCtxt, loggingContext) defer context.Clear(r) next(w, r) }
func (ah authHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) { //Check for header presence authzHeader := r.Header.Get("Authorization") if authzHeader == "" { log.Info("Missing Authorization header") w.WriteHeader(http.StatusUnauthorized) w.Write([]byte("Unauthorized\n")) return } claims, err := ah.rollAuthZ.ValidateAccessToken(authzHeader) if err != nil { log.Info(err.Error()) w.WriteHeader(http.StatusUnauthorized) w.Write([]byte("Unauthorized\n")) } //Check against the whitelist aud, ok := claims["aud"].(string) if !ok { log.Info("aud claim not present in token") w.WriteHeader(http.StatusUnauthorized) w.Write([]byte("Unauthorized\n")) return } if !ah.whiteListOK(aud) { log.Info("token failed whitelist check: ", aud) w.WriteHeader(http.StatusUnauthorized) w.Write([]byte("Unauthorized\n")) return } sub, ok := claims["sub"].(string) if !ok { log.Info("Unable to extract sub from token claims") w.WriteHeader(http.StatusUnauthorized) w.Write([]byte("Unauthorized\n")) return } context.Set(r, AuthzAdminScope, false) scope, ok := claims["scope"].(string) if ok && scope == "admin" { admin, err := ah.adminRepo.IsAdmin(sub) if err != nil { log.Info("error making admin scope determination: ", err.Error()) w.WriteHeader(http.StatusUnauthorized) w.Write([]byte("Unauthorized\n")) return } context.Set(r, AuthzAdminScope, admin) } context.Set(r, AuthzSubject, sub) ah.handler.ServeHTTP(w, r) context.Clear(r) }
func ClearContext() Adapter { return func(h http.Handler) http.Handler { return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { h.ServeHTTP(w, r) context.Clear(r) }) } }
// Middleware helps you set up a session in context func Middleware(name string, store Store) gin.HandlerFunc { return func(c *gin.Context) { c.Set(sessionName, name) c.Set(sessionStore, store) defer context.Clear(c.Request) c.Next() } }