From d517f36a29a6479e40c36bc08c715901c1ddf189 Mon Sep 17 00:00:00 2001 From: "Gerasimos (Makis) Maropoulos" Date: Mon, 19 Oct 2020 10:05:48 +0300 Subject: [PATCH] minor commit. But I am not happy with the jwt implementations for Go...they seem to produce enough performance cost, will try to make a jwt parser by myself and see the difference --- HISTORY.md | 2 +- configuration.go | 2 +- context/context.go | 10 +++++----- middleware/accesslog/accesslog.go | 2 +- middleware/jwt/jwt.go | 25 ++++++++++++++++++++----- 5 files changed, 28 insertions(+), 13 deletions(-) diff --git a/HISTORY.md b/HISTORY.md index 82990b49..30ca6fe1 100644 --- a/HISTORY.md +++ b/HISTORY.md @@ -317,7 +317,7 @@ var dirOpts = iris.DirOptions{ - `Context.TextYAML(interface{}) error` same as `Context.YAML` but with set the Content-Type to `text/yaml` instead (Google Chrome renders it as text). - `Context.IsDebug() bool` reports whether the application is running under debug/development mode. It is a shortcut of Application.Logger().Level >= golog.DebugLevel. - `Context.IsRecovered() bool` reports whether the current request was recovered from the [recover middleware](https://github.com/kataras/iris/tree/master/middleware/recover). Also the `Context.GetErrPublic() (bool, error)`, `Context.SetErrPrivate(err error)` methods and `iris.ErrPrivate` interface have been introduced. -- `Context.RecordBody()` same as the Application's `DisableBodyConsumptionOnUnmarshal` configuration field but registers per chain of handlers. It makes the request body readable more than once. +- `Context.RecordRequestBody(bool)` same as the Application's `DisableBodyConsumptionOnUnmarshal` configuration field but registers per chain of handlers. It makes the request body readable more than once. - `Context.IsRecordingBody() bool` reports whether the request body can be readen multiple times. - `Context.ReadHeaders(ptr interface{}) error` binds request headers to "ptr". [Example](https://github.com/kataras/iris/blob/master/_examples/request-body/read-headers/main.go). - `Context.ReadParams(ptr interface{}) error` binds dynamic path parameters to "ptr". [Example](https://github.com/kataras/iris/blob/master/_examples/request-body/read-params/main.go). diff --git a/configuration.go b/configuration.go index e653e7df..bc9f04e8 100644 --- a/configuration.go +++ b/configuration.go @@ -715,7 +715,7 @@ type Configuration struct { // The body will not be changed and existing data before the // context.UnmarshalBody/ReadJSON/ReadXML will be not consumed. // - // See `Context.RecordBody` method for the same feature, per-request. + // See `Context.RecordRequestBody` method for the same feature, per-request. DisableBodyConsumptionOnUnmarshal bool `ini:"disable_body_consumption" json:"disableBodyConsumptionOnUnmarshal,omitempty" yaml:"DisableBodyConsumptionOnUnmarshal" toml:"DisableBodyConsumptionOnUnmarshal"` // FireEmptyFormError returns if set to tue true then the `context.ReadBody/ReadForm` // will return an `iris.ErrEmptyForm` on empty request form data. diff --git a/context/context.go b/context/context.go index 3caff8d9..00edad58 100644 --- a/context/context.go +++ b/context/context.go @@ -2130,11 +2130,11 @@ func GetBody(r *http.Request, resetBody bool) ([]byte, error) { const disableRequestBodyConsumptionContextKey = "iris.request.body.record" -// RecordBody same as the Application's DisableBodyConsumptionOnUnmarshal configuration field -// but acts for the current request. +// RecordRequestBody same as the Application's DisableBodyConsumptionOnUnmarshal +// configuration field but acts only for the current request. // It makes the request body readable more than once. -func (ctx *Context) RecordBody() { - ctx.values.Set(disableRequestBodyConsumptionContextKey, true) +func (ctx *Context) RecordRequestBody(b bool) { + ctx.values.Set(disableRequestBodyConsumptionContextKey, b) } // IsRecordingBody reports whether the request body can be readen multiple times. @@ -2146,7 +2146,7 @@ func (ctx *Context) IsRecordingBody() bool { // GetBody reads and returns the request body. // The default behavior for the http request reader is to consume the data readen // but you can change that behavior by passing the `WithoutBodyConsumptionOnUnmarshal` Iris option -// or by calling the `RecordBody` method. +// or by calling the `RecordRequestBody` method. // // However, whenever you can use the `ctx.Request().Body` instead. func (ctx *Context) GetBody() ([]byte, error) { diff --git a/middleware/accesslog/accesslog.go b/middleware/accesslog/accesslog.go index 090cad81..195669b3 100644 --- a/middleware/accesslog/accesslog.go +++ b/middleware/accesslog/accesslog.go @@ -718,7 +718,7 @@ func (ac *AccessLog) Handler(ctx *context.Context) { // Enable reading the request body // multiple times (route handler and this middleware). if ac.shouldReadRequestBody() { - ctx.RecordBody() + ctx.RecordRequestBody(true) } // Set the fields context value so they can be modified diff --git a/middleware/jwt/jwt.go b/middleware/jwt/jwt.go index 3a69723a..a2d8172c 100644 --- a/middleware/jwt/jwt.go +++ b/middleware/jwt/jwt.go @@ -58,6 +58,8 @@ func FromJSON(jsonKey string) TokenExtractor { } var m context.Map + ctx.RecordRequestBody(true) + defer ctx.RecordRequestBody(false) if err := ctx.ReadJSON(&m); err != nil { return "" } @@ -362,6 +364,16 @@ func (j *JWT) token(maxAge time.Duration, claims interface{}) (string, error) { token, err = jwt.SignedAndEncrypted(j.Signer, j.Encrypter).Claims(c).CompactSerialize() } else { token, err = jwt.Signed(j.Signer).Claims(c).CompactSerialize() + // payload, pErr := Marshal(c) + // if pErr != nil { + // return "", pErr + // } + // sign, sErr := j.Signer.Sign(payload) + // if sErr != nil { + // return "", sErr + // } + + // token, err = sign.CompactSerialize() } if err != nil { @@ -409,6 +421,9 @@ func (j *JWT) VerifyToken(ctx *context.Context, claimsPtr interface{}, expectati func (j *JWT) VerifyRefreshToken(ctx *context.Context, claimsPtr interface{}, expectations ...Expectation) (*TokenInfo, error) { token := j.RequestToken(ctx) if token == "" { + ctx.RecordRequestBody(true) + defer ctx.RecordRequestBody(false) + var tokenPair TokenPair // read "refresh_token" from JSON. if ctx.GetContentTypeRequested() == context.ContentJSONHeaderValue { ctx.ReadJSON(&tokenPair) // ignore error. @@ -772,10 +787,10 @@ func (j *JWT) Verify(newPtr func() interface{}, expections ...Expectation) conte // VerifyMap is a shortcut of Verify with a function which will bind // the claims to a standard Go map[string]interface{}. -func (j *JWT) VerifyMap(exceptions ...Expectation) context.Handler { +func (j *JWT) VerifyMap(expections ...Expectation) context.Handler { return j.Verify(func() interface{} { return &context.Map{} - }) + }, expections...) } // VerifyJSON works like `Verify` but instead it @@ -797,7 +812,7 @@ func (j *JWT) VerifyMap(exceptions ...Expectation) context.Handler { func (j *JWT) VerifyJSON(expections ...Expectation) context.Handler { return j.Verify(func() interface{} { return new(json.RawMessage) - }) + }, expections...) } // ReadJSON is a helper which binds "claimsPtr" to the @@ -839,8 +854,8 @@ func (j *JWT) NewUser(opts ...UserOption) *User { // it unmarshals the token to the specific User type. // It sets the Context User too. So the next handler(s) // of the same chain can access the User through a `Context.User()` call. -func (j *JWT) VerifyUser() context.Handler { +func (j *JWT) VerifyUser(expectations ...Expectation) context.Handler { return j.Verify(func() interface{} { return new(User) - }) + }, expectations...) }