Many internet services use OAuth and email based protocols for sending login links and tokens.

I think it’s a pretty slick way to log users in and reduces overhead for them by adding yet another credential to their password managers.

I hadn’t found a python implementation I liked so I decided to implement a login credential issuer in pure python that I could use to send login links to users, similar to a slack-like login flow.

It didn’t take much code to implement! I’ll walk you through it.

I started by defining a basic class that could generate and validate a token.

Pypale stands for (Py)thon (Pa)ssword(le)ss.

import base64
import logging
import random
import string
import time

import jwt

class Pypale:
    ENCODING = "utf8"

    def __init__(self, token_ttl_minutes: int, base_url: str, secret_key: str,
                 token_issue_ttl_seconds: int):
        self.token_ttl_minutes = token_ttl_minutes
        self.base_url = base_url
        self.secret_key = secret_key
        self.token_issue_ttl_seconds = token_issue_ttl_seconds

    def generate_token(self):

    def validate_token(self):

Next I just filled in jwt building and field setting for building the token.

def generate_token(self, email: str) -> str:
    return base64.b64encode(

def generate_token_metadata(self, email: str) -> dict:
    return {
        "sub": email,
        "jti": self.one_time_nonce(),
        "iat": int(time.time()),
        "exp": int(time.time()) + (self.token_ttl_minutes * 60),
        "iss": self.base_url

def one_time_nonce(
        chars=string.ascii_letters + string.digits + "-") -> str:
    return "".join(random.choice(chars) for _ in range(size))

What’s a nonce? Read this.

Then I wrote a validator. I’m basically checking that the link click event occurs before the link expiry event, set by the iat + token_issue_ttl_seconds and that the user we’re checking for is the user that’s mentioned in the token.

def valid_token(self, return_token: str, return_email: str = "") -> bool:
        decoded_return_token = base64.b64decode(return_token).decode(
        token_metadata = jwt.decode(decoded_return_token,
        if (token_metadata["iat"] + self.token_issue_ttl_seconds) < int(
            logging.warning("Token was issued too long ago.")
            return False
        elif return_email != "":
            if token_metadata["sub"] != return_email:
                logging.warning("Token is not issued to the right user.")
                return False
            return True
            return True
    except Exception as e:
            f"Raised exception while validating login link: {e}")
        return False

And that’s pretty much it! I recently published this code for you to use in whatever project you want to integrate passwordless logins into.

You can checkout the package on github at and you can install it by running pip install pypale.

If you were following along and something didn’t look quite right, let me know; a twitter dm works just fine – and feel free to open a pull request or issue if you’d like to contribute to pypale.