My play application has an endpoint for receiving webhooks from Stripe.
In order to verify the webhooks, the request body needs to be compared against a signature and a signing key. This requires that I have access to the raw request body, as sent.
However, it seems that Play alters the request body, and I can't get access to the raw contents. This causes the computed signature to change, and the verification fails. More info: https://stackoverflow.com/a/43894244/49153
Here's my code:
@Singleton
class WebhookController @Inject()(cc : ControllerComponents,
env: Env)
(implicit ec: ExecutionContext)
extends AbstractController(cc) {
private val log = Logger("WebhookController")
def index(): Action[AnyContent] = Action.async { implicit req =>
val signature =
req.headers.headers.find(_._1 == "Stripe-Signature").map(_._2).getOrElse("").trim
if (verifySignature(req.body.toString, signature, env.webhookSecretKey))
Future.successful(ok("ok"))
else
Future.successful(ok("Couldn't verify signature"))
}
}
Here I'm trying to access the body using req.body.toString
but it looks to be the deserialized json rather than the raw body.
Using req.body.asRaw
returns a none.
Any ideas?