postgraphile docs: v5 JWT guide is lacking
<!-- Before opening an issue: if you use `npm` try running `yarn` instead; if
      you run `yarn`, please try running `npx yarn-deduplicate && yarn`. -->

### Summary

<!-- A brief summary of the problem. -->

Our documentation around JWTs is lacking in version 5 docs.  

From @Benjie: 
> We removed JWT verification by default in V5, but it’s added either by the v4 preset or by the lazy-jwt preset. We’re hoping people will do their own JWT to cover refresh tokens and the like, also I loathe JWT

> More information can be found here: https://postgraphile.org/postgraphile/next/config/#making-http-data-available-to-plan-resolvers

>  Also why I don’t like JWT for this: https://sprout.io/Benjie/13938-why-i-dont-use-jwt-for-sessions

### Discord Discussion

From our [community Discord](https://discord.com/channels/489127045289476126/1339058138371850383/1339058138371850383) user rohoon: 

> I'm trying out V5 and am having a problem getting the Authorization header to be recognised. The schema I have works perfectly in V4.

> My `authorize` mutation is producing a JWT that looks fine when I decode it, but when I add the token in the `Authorization` header (tried both Ruru and Insomnia), the claims aren't visible in my queries and my `current_user_account_id` function is returning null.

![Image](https://github.com/user-attachments/assets/c60f3338-3908-471e-885a-278d33ec1407)

> Here is my graphile.config.js:

```
import { PostGraphileAmberPreset } from "postgraphile/presets/amber";

/** @type {GraphileConfig.Preset} */
const preset = {
    extends: [PostGraphileAmberPreset],
    gather: {
        pgJwtTypes: "public.jwt_token",
    },
    schema: {
        pgJwtSecret: process.env.JWT_SECRET,
    },
};

export default preset;
```

> And my authentication SQL, which works fine in V4:

```

-- Gets the current user ID.
CREATE OR REPLACE FUNCTION current_user_account_id() RETURNS UUID
  AS $$ SELECT current_setting('jwt.claims.user_id', true)::UUID $$
  LANGUAGE SQL STABLE;

-- Gets the current user role.
CREATE OR REPLACE FUNCTION current_user_account_role() RETURNS TEXT
  AS $$ SELECT current_setting('jwt.claims.role', true)::TEXT $$
  LANGUAGE SQL STABLE;

-- Defines the structure of JWTs used for authentication.
DROP TYPE IF EXISTS jwt_token CASCADE;
CREATE TYPE jwt_token AS (
  username   VARCHAR(64),
  role       VARCHAR(32),
  first_name VARCHAR(64),
  last_name  VARCHAR(64),
  user_id    UUID,
  exp        INTEGER
);

-- Authenticates a user with the given username and password.
CREATE OR REPLACE FUNCTION authenticate(
  username TEXT,
  password TEXT
) RETURNS jwt_token AS $$
DECLARE
  login private.login;
  found_user user_account;
BEGIN
  SELECT * INTO login
    FROM private.login
    WHERE private.login.provider = 'JWT'
    AND private.login.username = authenticate.username;

  SELECT * INTO found_user
    FROM user_account
    WHERE user_account.id = login.user_account_id;

  IF login.password_hash = crypt(password, login.password_hash) THEN
    RETURN (
      login.username,
      found_user.role,
      found_user.first_name,
      found_user.last_name,
      login.user_account_id,
      extract(epoch from now() + interval '7 days')
    )::jwt_token;
  ELSE
    RAISE EXCEPTION 'Invalid credentials' USING ERRCODE = 'invalid_password';
  END IF;
END;
$$ LANGUAGE PLPGSQL STRICT SECURITY DEFINER;
```

> I've also set the `JWT_SECRET` variable (just to `"secret"` for testing).  
> I just tried the same thing with pretty much the exact code from the [docs](https://postgraphile.org/postgraphile/next/security) and got the same result.

```
create extension if not exists pgcrypto;

drop table if exists person_account;
create table person_account (
  id serial primary key,
  email text not null unique,
  password_hash text not null,
  is_admin boolean not null default false
);
insert into person_account (email, password_hash, is_admin) values ('admin@example.com', crypt('admin', gen_salt('bf')), true);

drop type if exists jwt_token cascade;
create type jwt_token as (
  role text,
  exp integer,
  person_id integer,
  is_admin boolean,
  username varchar
);

create or replace function authenticate(
  email text,
  password text
)
returns jwt_token
as $$
declare
  account person_account;
begin
  select a.* into account
    from person_account as a
    where a.email = authenticate.email;

  if account.password_hash = crypt(password, account.password_hash) then
    return (
      'person_role',
      extract(epoch from now() + interval '7 days'),
      account.id,
      account.is_admin,
      account.email
    )::jwt_token;
  else
    return null;
  end if;
end;
$$ language plpgsql strict security definer;

create or replace function current_user_id() returns integer as $$
  select nullif(current_setting('jwt.claims.user_id', true), '')::integer;
$$ language sql stable;
```

> I just tried the exact same setup as above with the V4 CLI and it works fine:

![Image](https://github.com/user-attachments/assets/7d26be64-142d-4247-9dcd-d5a70e4dd779)