Module slack_sdk.signature
Slack request signature verifier
Classes
class Clock
-
Expand source code
class Clock: def now(self) -> float: # skipcq: PYL-R0201 return time()
Methods
def now(self) ‑> float
class SignatureVerifier (signing_secret: str, clock: Clock = <slack_sdk.signature.Clock object>)
-
Slack request signature verifier
Slack signs its requests using a secret that's unique to your app. With the help of signing secrets, your app can more confidently verify whether requests from us are authentic. https://api.slack.com/authentication/verifying-requests-from-slack
Expand source code
class SignatureVerifier: def __init__(self, signing_secret: str, clock: Clock = Clock()): """Slack request signature verifier Slack signs its requests using a secret that's unique to your app. With the help of signing secrets, your app can more confidently verify whether requests from us are authentic. https://api.slack.com/authentication/verifying-requests-from-slack """ self.signing_secret = signing_secret self.clock = clock def is_valid_request( self, body: Union[str, bytes], headers: Dict[str, str], ) -> bool: """Verifies if the given signature is valid""" if headers is None: return False normalized_headers = {k.lower(): v for k, v in headers.items()} return self.is_valid( body=body, timestamp=normalized_headers.get("x-slack-request-timestamp", None), signature=normalized_headers.get("x-slack-signature", None), ) def is_valid( self, body: Union[str, bytes], timestamp: str, signature: str, ) -> bool: """Verifies if the given signature is valid""" if timestamp is None or signature is None: return False if abs(self.clock.now() - int(timestamp)) > 60 * 5: return False calculated_signature = self.generate_signature(timestamp=timestamp, body=body) if calculated_signature is None: return False return hmac.compare_digest(calculated_signature, signature) def generate_signature(self, *, timestamp: str, body: Union[str, bytes]) -> Optional[str]: """Generates a signature""" if timestamp is None: return None if body is None: body = "" if isinstance(body, bytes): body = body.decode("utf-8") format_req = str.encode(f"v0:{timestamp}:{body}") encoded_secret = str.encode(self.signing_secret) request_hash = hmac.new(encoded_secret, format_req, hashlib.sha256).hexdigest() calculated_signature = f"v0={request_hash}" return calculated_signature
Methods
def generate_signature(self, *, timestamp: str, body: Union[str, bytes]) ‑> Optional[str]
-
Generates a signature
def is_valid(self, body: Union[str, bytes], timestamp: str, signature: str) ‑> bool
-
Verifies if the given signature is valid
def is_valid_request(self, body: Union[str, bytes], headers: Dict[str, str]) ‑> bool
-
Verifies if the given signature is valid