func ParseFromRequest(req engine.Request, keyFunc jwt.Keyfunc) (token *jwt.Token, err error) { // Look for an Authorization header if ah := req.Header().Get("Authorization"); ah != "" { // Should be a bearer token if len(ah) > 6 && strings.ToUpper(ah[0:6]) == "BEARER" { return jwt.Parse(ah[7:], keyFunc) } } // Look for "access_token" parameter if tokStr := req.FormValue("access_token"); tokStr != "" { return jwt.Parse(tokStr, keyFunc) } return nil, jwt.ErrNoTokenInRequest }
// RemoteIP finds IP Address given http.Request struct. func RemoteIP(ipLookups []string, r engine.Request) string { realIP := r.Header().Get("X-Real-IP") forwardedFor := r.Header().Get("X-Forwarded-For") for _, lookup := range ipLookups { if lookup == "RemoteAddr" { return ipAddrFromRemoteAddr(r.RemoteAddress()) } if lookup == "X-Forwarded-For" && forwardedFor != "" { // X-Forwarded-For is potentially a list of addresses separated with "," parts := strings.Split(forwardedFor, ",") for i, p := range parts { parts[i] = strings.TrimSpace(p) } return parts[0] } if lookup == "X-Real-IP" && realIP != "" { return realIP } } return "" }
// BuildKeys generates a slice of keys to rate-limit by given config and request structs. func BuildKeys(limiter *config.Limiter, r engine.Request) [][]string { remoteIP := RemoteIP(limiter.IPLookups, r) path := r.URL().Path() sliceKeys := make([][]string, 0) // Don't BuildKeys if remoteIP is blank. if remoteIP == "" { return sliceKeys } if limiter.Methods != nil && limiter.Headers != nil && limiter.BasicAuthUsers != nil { // Limit by HTTP methods and HTTP headers+values and Basic Auth credentials. if StringInSlice(limiter.Methods, r.Method()) { for headerKey, headerValues := range limiter.Headers { if (headerValues == nil || len(headerValues) <= 0) && r.Header().Get(headerKey) != "" { // If header values are empty, rate-limit all request with headerKey. username, _, ok := r.BasicAuth() if ok && libstring.StringInSlice(limiter.BasicAuthUsers, username) { sliceKeys = append(sliceKeys, []string{remoteIP, path, r.Method(), headerKey, username}) } } else if len(headerValues) > 0 && r.Header().Get(headerKey) != "" { // If header values are not empty, rate-limit all request with headerKey and headerValues. for _, headerValue := range headerValues { username, _, ok := r.BasicAuth() if ok && libstring.StringInSlice(limiter.BasicAuthUsers, username) { sliceKeys = append(sliceKeys, []string{remoteIP, path, r.Method(), headerKey, headerValue, username}) } } } } } } else if limiter.Methods != nil && limiter.Headers != nil { // Limit by HTTP methods and HTTP headers+values. if libstring.StringInSlice(limiter.Methods, r.Method()) { for headerKey, headerValues := range limiter.Headers { if (headerValues == nil || len(headerValues) <= 0) && r.Header().Get(headerKey) != "" { // If header values are empty, rate-limit all request with headerKey. sliceKeys = append(sliceKeys, []string{remoteIP, path, r.Method(), headerKey}) } else if len(headerValues) > 0 && r.Header().Get(headerKey) != "" { // If header values are not empty, rate-limit all request with headerKey and headerValues. for _, headerValue := range headerValues { sliceKeys = append(sliceKeys, []string{remoteIP, path, r.Method(), headerKey, headerValue}) } } } } } else if limiter.Methods != nil && limiter.BasicAuthUsers != nil { // Limit by HTTP methods and Basic Auth credentials. if libstring.StringInSlice(limiter.Methods, r.Method()) { username, _, ok := r.BasicAuth() if ok && libstring.StringInSlice(limiter.BasicAuthUsers, username) { sliceKeys = append(sliceKeys, []string{remoteIP, path, r.Method(), username}) } } } else if limiter.Methods != nil { // Limit by HTTP methods. if libstring.StringInSlice(limiter.Methods, r.Method()) { sliceKeys = append(sliceKeys, []string{remoteIP, path, r.Method()}) } } else if limiter.Headers != nil { // Limit by HTTP headers+values. for headerKey, headerValues := range limiter.Headers { if (headerValues == nil || len(headerValues) <= 0) && r.Header().Get(headerKey) != "" { // If header values are empty, rate-limit all request with headerKey. sliceKeys = append(sliceKeys, []string{remoteIP, path, headerKey}) } else if len(headerValues) > 0 && r.Header().Get(headerKey) != "" { // If header values are not empty, rate-limit all request with headerKey and headerValues. for _, headerValue := range headerValues { sliceKeys = append(sliceKeys, []string{remoteIP, path, headerKey, headerValue}) } } } } else if limiter.BasicAuthUsers != nil { // Limit by Basic Auth credentials. username, _, ok := r.BasicAuth() if ok && libstring.StringInSlice(limiter.BasicAuthUsers, username) { sliceKeys = append(sliceKeys, []string{remoteIP, path, username}) } } else { // Default: Limit by remoteIP and path. sliceKeys = append(sliceKeys, []string{remoteIP, path}) } return sliceKeys }