code returned in the first step of authorization and attempt to use it to authorize their own app before the legitimate app exchanges it for an access_token. In the case of the Authorization Code Flow this is prevented by the fact that the pre-shared Client Secret is not known to the malicious actor so they don’t have enough information to do the complete code exchange.
Due to the nature of in-browser single-page apps with no backend, or mobile apps where secrets can be extracted from the app if distributed within the app, there is sometimes no location to safely store the client_secret. We call these “Public” apps. For these apps, we implement a variant of the Authorization Code Flow using PKCE (Proof Key for Code Exchange). This flow uses an extension to the Authorization Code Flow to ensure both requests used during the Authorization Code Flow come from the same Connected App.
When beginning the authorization request, the Connected App will construct a code_verifier by generating a cryptographically random value. The Connected App will use the code_verifier to generate a code_challenge. The code_challenge is the SHA-256 hash of the code_verifier. On the initial request to Stytch—the request made to the page hosting the <IdentityProvider /> component—the additional URL parameters of code_challenge and code_challenge_method should be sent:
| Name | Meaning |
|---|---|
code_challenge | The SHA-256 hash of the value of the code_verifier |
code_challenge_method | The method of hashing the code_verifier. For Stytch this should always be S256 |
code_challenge for later. After the user has granted permission for access, Stytch will return a code from this step just as in the regular Authorization Code Flow.
During the code exchange part of the process, the Public app will exchange the code for an access_token as the server would do in the Authorization Code Flow. However, the Public app has no access to a client_secret so cannot send that parameter. The Public app instead sends the original code_verifier with this request:
| Name | Meaning |
|---|---|
code_verifier | The original value used to generate the code_challenge |
code_challenge was generated from this code_verifier before generating and returning credentials for the app. In this way Stytch can be sure that the app that requested the code in the first request is the same app that is requesting the access_token in the second request.