def _get_xsrf_token_cookie(handler):
    """
    Get the _valid_ XSRF token and id from Cookie

    Returns (xsrf_token, xsrf_id) found in Cookies header.

    multiple xsrf cookies may be set on multiple paths;

    RFC 6265 states that they should be in order of more specific path to less,
    but ALSO states that servers should never rely on order.

    Tornado (6.4) and stdlib (3.12) SimpleCookie explicitly use the _last_ value,
    which means the cookie with the _least_ specific prefix will be used if more than one is present.

    Because we sign values, we can get the first valid cookie and not worry about order too much.

    This is simplified from tornado's HTTPRequest.cookies property
    only looking for a single cookie.
    """

    if "Cookie" not in handler.request.headers:
        return (None, None)

    for chunk in handler.request.headers["Cookie"].split(";"):
        key = chunk.partition("=")[0].strip()
        if key != "_xsrf":
            # we are only looking for the _xsrf cookie
            # ignore everything else
            continue

        # use stdlib parsing to handle quotes, validation, etc.
        try:
            xsrf_token = SimpleCookie(chunk)[key].value.encode("ascii")
        except (ValueError, KeyError):
            continue

        xsrf_token_id = _get_signed_value_urlsafe(handler, "_xsrf", xsrf_token)

        if xsrf_token_id:
            # only return if we found a _valid_ xsrf cookie
            # otherwise, keep looking
            return (xsrf_token, xsrf_token_id)
    # no valid token found found
    return (None, None)
Get the _valid_ XSRF token and id from Cookie

Returns (xsrf_token, xsrf_id) found in Cookies header.

multiple xsrf cookies may be set on multiple paths;

RFC 6265 states that they should be in order of more specific path to less,
but ALSO states that servers should never rely on order.

Tornado (6.4) and stdlib (3.12) SimpleCookie explicitly use the _last_ value,
which means the cookie with the _least_ specific prefix will be used if more than one is present.

Because we sign values, we can get the first valid cookie and not worry about order too much.

This is simplified from tornado's HTTPRequest.cookies property
only looking for a single cookie.
jupyterhub/_xsrf_utils.py