imbo / behat-api-extension

API extension for Behat, used to ease testing of JSON-based APIs
MIT License
109 stars 42 forks source link

Add Oauth 2 JWT token support #54

Closed Zwartpet closed 7 years ago

Zwartpet commented 7 years ago

Added a method to test JWT tokens

Zwartpet commented 7 years ago

According to travis the build is succeeded: https://travis-ci.org/imbo/behat-api-extension but github is waiting for the status.

christeredvartsen commented 7 years ago

I noticed. Tried to re-run the Travis-build, but it didn't help.

Zwartpet commented 7 years ago

So can this be merged?

christeredvartsen commented 7 years ago

So can this be merged?

I will try to look through it later today to see if I can merge it.

christeredvartsen commented 7 years ago

Currently it's only possible to match a JWT that is in the first level of the JSON response. If the response contains for instance:

{
  "some": {
    "nested": {
      "object": {
        "with": {
          "jwt": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiYWRtaW4iOnRydWV9.TJVA95OrM7E2cBab30RMHrHDcEfxjoYZgeFONFh7HgQ"
        }
      }
    }
  }
}

It would be great if one could m atch this as well, also values in numericallly indexed arrays. Perhaps use a notation like some.nested.object.with.jwt (to match the above example), and also support [<index>] to be able to match JWTs in lists?

christeredvartsen commented 7 years ago

It would be nice to be able to use the Then the response body contains JSON: step, and perhaps add a @jwt() custom matcher function. Since these "functions" doesn't handle nested objects as params, as this could generate invalid JSON, we could create another step which holds the decoded JWT and give them an identifier, which we then could reference in the @jwt() matcher.

Then we could do something like this:

Then the response body contains a JWT identified by "some JWT reference":
    """
    {
      "header": {
        "alg": "HS256",
        "typ": "JWT"
      },
      "claims": {
        "sub": "some subject",
        "iss": "some issuer"
      },
      "secret": "some secret"
    }
    """
And the response body contains JSON:
    """
    {
        "some": {
            "object": {
                "with": {
                    "value": "@jwt(some JWT reference)"
                }
            }
        }
    }
    """

The two steps can then be used together to be able to match JWTs placed anywhere in the body. Does this sound OK @Zwartpet?

Zwartpet commented 7 years ago

Sounds good to me, i'm not able to update the code in the upcoming days though. Probably after the weekend.

christeredvartsen commented 7 years ago

I can push to your branch though, so I can hack together something tonight.

Zwartpet commented 7 years ago

Then I'll keep an eye on my inbox to see you're implementation ;)

Zwartpet commented 7 years ago

Looks good, is there anything else need to be done?