Reposting this issue here as requested in [IMPORTANT] Stop creating issues here, use the Shopify Community forum instead · Issue #2521 · Shopify/ui-extensions · GitHub
Please list the package(s) involved in the issue, and include the version you are using
@shopify/ui-extensions-react@2024.1.1
Describe the bug
useSessionToken
produces a SessionToken
. SessionToken.get()
is annotated with the following note:
// https://github.com/Shopify/ui-extensions/blob/c22cbdaf0b3bcc887aa554c30bfdbcdeb4d96750/packages/ui-extensions/src/surfaces/checkout/api/standard/standard.ts#L733-L741
export interface SessionToken {
/**
* Requests a session token that hasn't expired. You should call this method every
* time you need to make a request to your backend in order to get a valid token.
* This method will return cached tokens when possible, so you don’t need to worry
* about storing these tokens yourself.
*/
get(): Promise<string>;
}
Also, SessionToken.jti
is described]() as “A unique identifier (a nonce) to prevent replay attacks”.
// https://github.com/Shopify/ui-extensions/blob/c22cbdaf0b3bcc887aa554c30bfdbcdeb4d96750/packages/ui-extensions/docs/surfaces/checkout/reference/examples/session-token-jwt.example.json#L12-L13
// A unique identifier (a nonce) to prevent replay attacks
"jti": "6c992878-dbaf-48d1-bb9d-6d9b59814fd1",
In order to effectively use SessionToken.jti
to prevent replay attacks, my backend server should reject requests that include session tokens that have already been sent. This requires my checkout extension frontend to send a new session token for each request to my backend server.
However, I cannot generate a new session token for each request because SessionToken.get()
returns cached tokens. Therefore my backend server thinks that subsequent requests from the frontend are replay attacks, and rejects the requests.
Steps to reproduce the behavior:
- Generate a session token with
SessionToken.get()
. - Send the token to your backend server in the Authorization header.
- Try to generate a new session token with
SessionToken.get()
. You should end up with the same session token as before. - Sending the token to your backend server will be rejected as a replay attack.
Expected behavior
SessionToken.get()
should not cache tokens. Instead, each call to SessionToken.get()
should return a new token.