Skip to content

Quickstart

This page shows the smallest useful backend flow.

Create an authenticator

from datetime import timedelta

from vk_miniapp_auth import VKMiniAppAuthenticator

authenticator = VKMiniAppAuthenticator(
    app_id=53377165,
    app_secret="secure-key-from-vk-settings",
    ttl=timedelta(hours=1),
)

The default TTL is one hour. Pass a custom datetime.timedelta when your application needs a shorter or longer acceptance window.

Validate a request

from vk_miniapp_auth.errors import InvalidInitDataError


def get_verified_vk_user_id(authorization_header: str) -> int:
    try:
        launch_params = authenticator.get_verified_launch_params(authorization_header)
    except InvalidInitDataError as exc:
        raise PermissionError("Invalid VK launch parameters") from exc

    if launch_params is None:
        raise PermissionError("Invalid VK launch signature")

    return launch_params.vk_user_id

Use the returned vk_user_id only after get_verified_launch_params() returns a VkLaunchParams object. The helper returns None when the parsed launch parameters fail the app ID, TTL, or signature checks.

Send launch data from the client

The package expects the authorization value to contain a base64-encoded URL with the VK launch query string. Keep the secure key on the backend; the client only forwards launch data it received from VK.

const launchUrl = window.location.href
const token = btoa(launchUrl)

await fetch("/api/me", {
  headers: {
    Authorization: token,
  },
})

Note

If your frontend framework already provides a backend token transport, you can use that instead. The backend still needs the original VK launch parameters to verify the signature.

Handle failures consistently

Treat all validation failures as authentication failures:

  • malformed base64 or query string;
  • missing required launch parameters;
  • wrong vk_app_id;
  • expired vk_ts;
  • mismatched sign.

Avoid returning detailed signature errors to end users. Detailed logs are useful internally, but public responses should stay generic.

Parse without trusting

Use get_launch_params() only when you intentionally need a parse-only step:

launch_params = authenticator.get_launch_params(authorization_header)
if launch_params is None or not authenticator.is_signed(launch_params):
    raise PermissionError("Invalid VK launch signature")

get_launch_params() converts fields into Python types and raises InvalidInitDataError for malformed data, but it does not verify the signature by itself.