Verifying Slack requests in Python

If you’re building a Slack app in Python, you’ll need to verify that the inbound callbacks you’re receiving are genuine.

This page in the Slack API docs explains the process in pseudocode: Verifying requests from Slack

Below is a Python function, based on that pseudocode, which will simply return True if the request is valid, and False if not. This has been tested using a Flask request object, but should be easily adaptable to any other web framework.

import hmac
import hashlib
import time

def verify_request(request):
    SIGNING_SECRET = "your_slack_signing_secret"

    # Convert your signing secret to bytes
    slack_signing_secret = bytes(SIGNING_SECRET, "utf-8")

    request_body = request.get_data().decode()

    slack_request_timestamp = request.headers["X-Slack-Request-Timestamp"]
    slack_signature = request.headers["X-Slack-Signature"]

    # Check that the request is no more than 60 seconds old
    if (int(time.time()) - int(slack_request_timestamp)) > 60:
        print("Verification failed. Request is out of date.")
        return False

    # Create a basestring by concatenating the version, the request  
      timestamp, and the request body
    basestring = f"v0:{slack_request_timestamp}:{request_body}".encode("utf-8")

    # Hash the basestring using your signing secret, take the hex digest, and prefix with the version number
    my_signature = (
        "v0=" + hmac.new(slack_signing_secret, basestring, hashlib.sha256).hexdigest()
    )

    # Compare the resulting signature with the signature on the request to verify the request
    if hmac.compare_digest(my_signature, slack_signature):
        return True
    else:
        print("Verification failed. Signature invalid.")
        return False

This could also be implemented as a Python decorator (if I get a chance I’ll update this post with an example of that too).