Mobile-based Applications
Native mobile applications on different mobile operating systems can gain authorized access to Zoho's APIs via OAuth. The authorization flow is similar to the server-based application flow. The mobile device must additionally provide an app schema, so the redirection can be caught by the mobile application.
Authorization code flow with PKCE
Mobile and desktop-based apps can communicate with Zoho and obtain the access token using the authorization code flow. Since, mobile and desktop apps are public clients, the Proof Key for Code Exchange (PKCE) extension must also be used to obtain the access token.
Note: Previously, PKCE was not mandated for mobile and desktop apps. Apps previously registered with Zoho that haven't supported PKCE can still obtain access tokens. However, it is strongly advised to support the PKCE extension from now on to improve the security of your app.
Why is PKCE needed
When public clients use the authorization code flow, there is a risk of an "authorization code inception attack" due to the following reasons:
- Multiple apps can register themselves as a handler for a redirect URL. Hence, a malicious app (by using the same redirect URL as the original app) can intercept the authorization code when the browser returns it from the Zoho server.
- A public client cannot store the client credentials securely. Hence, a malicious app will be able to steal the client secret, pose itself as the original app, then exchange the intercepted authorization code for an access token.
PKCE mitigates this attack, and ensures the access token is provided only to the correct app and not to any malicious app.
How PKCE works
Prerequisite: Refer to the authorization code flow to understand the the fundamental workflow of getting access tokens.
In regular authorization code flow, the app will open the browser and initiate the OAuth flow. However, with the PKCE extension, before opening the browser, the app will generate a code_verifier and code_challenge, then proceeds with the OAuth flow.
The PKCE flow will be as follows:
- When the app wants to access a Zoho resource, it generates a code_verifier and code_challenge. The code_verifier is a random cryptographically-generated code, and code_challenge is a transformed version of code_verifier.
- The app opens the browser and sends a request to Zoho to obtain an authorization code (oauth/v2/auth). The code_challenge and the code_challenge_method (i.e., the method used for the transformation) are included as parameters in this request.
- After authenticating the user, Zoho provides an authorization code, and stores the code_challenge and the code_challenge_method.
- The browser returns the authorization code to the app via the redirect URL.
- The app sends the authorization code to Zoho in exchange for an access token (oauth/v2/token). The code_verifier is included as a parameter in this request.
- Zoho will transform the code_verifier using the code_challenge_method, then compares the transformed version with the stored code_challenge.
- If both the transformed code_verifier and the stored code_challenge matches, Zoho returns an access token to the app. If not, an error response will be returned.
How to implement authorization code flow with PKCE
Step 1: Generate code_verifier
The code_verifier is a cryptographically-generated random string. The code_verifier must:
- Be created using the unreserved characters: [A-Z] / [a-z] / [0-9] / "-" / "." / "_" / "~".
- Have a minimum length of 43 characters and maximum length of 128 characters.
- Have a high entropy value and must be impossible to guess.
Step 2: Transform code_verifier into code_challenge
The code_verifier can be transformed into code_challenge using the following methods:
- SHA256 (recommended)
code_challenge = BASE64URL-ENCODE(SHA256(ASCII(code_verifier))) - Plain
code_challenge = code_verifier
If the client can support the SHA256 method, it is mandatory to use this method. The plain method should be used only if the client is unable to support SHA256.
The issue with the plain method is that it can mitigate the attack if the malicious app can only observe the responses. If a malicious app is able to observe the requests, then the plain method will be ineffective as the app will be able to steal the code_verifier and use it to obtain the access token, since the code_verifier is the same as the code_challenge.
Step 3: Send an authorization request with code_challenge included
Follow this API reference doc to send an authorization request and obtain the authorization code.
Step 4: Send an access token request with code_verifier included
Follow this API reference doc to send an access token request and obtain the access token.