Skip to content
Back to Blog
·9 min read·technology

API Authentication: API Keys vs OAuth 2.0 vs JWT

API keys, OAuth 2.0, and JWT explained for Indian developers — when to use each, common mistakes like alg:none and localStorage, and securing fintech APIs.

BR

Bachao.AI Research Team

Cybersecurity Research

Scan Your Attack Surface

Security exposure this creates

Unpatched vulnerabilities in your tech stack are the #1 entry point for breaches targeting Indian businesses. Here's what to watch.

API authentication is the first line of defense for any web service. API keys are static credentials passed in headers or query strings — simple but brittle. OAuth 2.0 is a delegated authorization framework defined in IETF RFC 6749 that lets a user grant scoped access to a third party without sharing credentials. JWTs (JSON Web Tokens) are signed, self-contained tokens that carry claims and can be verified without a database lookup. For Indian developers building fintech, B2B SaaS, or compliance-heavy APIs, picking the wrong scheme is not just a technical inconvenience — it is an exploitable security gap.

What Are API Keys and When Should You Use Them

An API key is a long, random string — typically 32 to 64 hex characters — issued by a service and passed in an Authorization: Bearer <key> header or an X-API-Key header. The server validates it by looking it up in a database row.

Use API keys when:

    1. The caller is a server-to-server integration (no human in the loop)
    2. You need simplicity: one key, one service account, tightly scoped permissions
    3. Revocation speed matters (invalidating a row is instant)
    4. You are exposing a public data API (weather, currency, stock ticker) to paying customers
Do not use API keys when:
    1. The client is a mobile app or browser-side JavaScript — the key will be extracted
    2. You need to delegate access on behalf of a human user (OAuth 2.0 is the right tool)
    3. You need fine-grained per-user scopes
🚨
DANGER
Never embed an API key inside Android/iOS app binaries, browser JavaScript bundles, or public GitHub repositories. Attackers routinely scan GitHub for leaked keys. A static key in client code equals a credential breach — it cannot be rotated silently once it is in the wild.

How OAuth 2.0 Works

OAuth 2.0 defines four flows (grant types). The most important for web and mobile applications is the Authorization Code Flow with PKCE (Proof Key for Code Exchange), which prevents authorization code interception on mobile devices.

graph TD A[User opens app] --> B[App redirects to Auth Server] B --> C[User logs in and consents] C --> D{Auth Server issues
Authorization Code} D --> E[App exchanges code
for Access Token] E --> F[App calls API
with Access Token] F --> G{API validates token} G --> H[Success - return data] G --> I[Failure - 401 Unauthorized] style A fill:#1e3a5f,stroke:#3B82F6,color:#e2e8f0 style B fill:#1e3a5f,stroke:#3B82F6,color:#e2e8f0 style C fill:#1e3a5f,stroke:#3B82F6,color:#e2e8f0 style D fill:#1e3a5f,stroke:#3B82F6,color:#e2e8f0 style E fill:#1e3a5f,stroke:#3B82F6,color:#e2e8f0 style F fill:#1e3a5f,stroke:#3B82F6,color:#e2e8f0 style G fill:#1e3a5f,stroke:#3B82F6,color:#e2e8f0 style H fill:#1e3d2f,stroke:#10B981,color:#e2e8f0 style I fill:#5f1e1e,stroke:#EF4444,color:#e2e8f0

The key advantage of OAuth 2.0 is delegation with minimal privilege. A user can grant your payroll integration read-only access to their accounting software without handing over their password. Access tokens expire (typically 15–60 minutes). Refresh tokens allow silent renewal. Revoking a refresh token cuts off access entirely.

The four standard grant types:

Grant TypeUse CaseToken Lifetime
Authorization Code + PKCEWeb/mobile apps acting on behalf of a userShort-lived access + long-lived refresh
Client CredentialsServer-to-server (no user involved)Short-lived, non-refreshable
Device CodeSmart TV / CLI with no browserShort-lived
Implicit (deprecated)Legacy SPAs — do not useShort-lived, no refresh
⚠️
WARNING
The Implicit grant type is deprecated in OAuth 2.0 Security Best Current Practice (RFC 9700). Never implement it in new code. Indian fintech startups building on open banking (AA framework) or UPI integrations that still use implicit flow are carrying a known vulnerability.

How JWT Authentication Works

A JSON Web Token consists of three base64url-encoded parts separated by dots: header.payload.signature. The header specifies the signing algorithm (RS256, ES256, HS256). The payload contains claims: sub (subject/user id), iss (issuer), aud (audience), exp (expiry Unix timestamp), iat (issued at), and any custom claims your API needs. The signature is computed over the header and payload.

Your API server validates the JWT by:

  1. Decoding the header to get the algorithm
  2. Fetching the public key from the issuer's JWKS endpoint (for asymmetric schemes)
  3. Verifying the signature
  4. Checking exp (reject if expired), iss, and aud
  5. Extracting claims from the payload to make authorization decisions — without a database hit
The "without a database hit" property is the main reason JWTs are popular at scale. Stateless validation means your API pods can verify tokens independently.

Common JWT Mistakes Indian Developers Make

1. Accepting alg: none

The JWT spec originally allowed a none algorithm, meaning no signature. An attacker crafts a token with any payload and sets alg: "none". Naive libraries accepted it. Always use a whitelist: RS256 or ES256 for production, never accept none.

2. Using HS256 with a weak or shared secret

HS256 is an HMAC shared secret. If your auth server and API server share the same secret, and that secret leaks (e.g., environment variable in a Docker Hub public image), every token can be forged. Prefer RS256 — the auth server holds the private key, the API only needs the public key.

3. Storing JWT in localStorage

localStorage is accessible to any JavaScript on the page. An XSS vulnerability anywhere in your app — including third-party widgets, analytics SDKs, or ad scripts — can exfiltrate the token. Store access tokens in memory (a React state variable or module-level variable). Store refresh tokens in HttpOnly; Secure; SameSite=Strict cookies that JavaScript cannot read.

4. No expiry or excessively long expiry

A JWT with exp set to 30 days is effectively a password that never rotates. If an attacker obtains it (logs, referrer headers, XSS), they have persistent access. Best practice: access token TTL of 15 minutes, refresh token TTL of 7–30 days stored server-side and revocable.

5. Not validating aud and iss

If your platform issues JWTs for multiple services, always validate the aud (audience) claim. A token issued for your analytics API should not be accepted by your payments API. Skipping audience validation enables cross-service token replay.

🛡️
SECURITY
Per OWASP API Security Top 10 (2023), broken authentication is the second-most-critical API risk. Weak JWT validation — especially alg: none acceptance and missing exp checks — directly maps to this finding and is the most common root cause in API penetration tests performed on Indian SaaS platforms.

Know your vulnerabilities before attackers do

Run a free VAPT scan — takes 5 minutes, no signup required.

Book Your Free Scan

Comparing the Three Approaches

xychart-beta title "Use-Case Fit Score by Authentication Scheme" x-axis ["Server-to-Server", "User Delegation", "Stateless Scale", "Mobile Apps", "Token Revocation"] y-axis "Fit Score" 0 --> 10 bar [9, 2, 5, 2, 9] bar [5, 10, 7, 9, 7] bar [6, 6, 10, 7, 4]

Bars left to right: API Keys, OAuth 2.0, JWT. Higher is better fit for that use case.

77%of breaches involve stolen credentials or brute force as the entry vector (Verizon DBIR 2024)
$4.88Maverage global cost of a data breach — credential and authentication failures are a leading cause (IBM Cost of a Data Breach 2024)

Token Storage Best Practices

Token TypeCorrect StorageNever Store Here
JWT access tokenIn-memory (JS variable / React state)localStorage, sessionStorage, non-HttpOnly cookie
JWT refresh tokenHttpOnly; Secure; SameSite=Strict cookielocalStorage, URL params
API key (server side)Environment variable, secrets manager (AWS SSM / GCP Secret Manager).env committed to git, application DB in plain text
OAuth access token (mobile)OS keychain (Android Keystore / iOS Secure Enclave)SharedPreferences (Android), NSUserDefaults (iOS)

Refresh Tokens and Rotation

A refresh token is a long-lived credential used to obtain new access tokens after they expire. The correct pattern is refresh token rotation: every time you use a refresh token, the server issues a new refresh token and invalidates the old one. If an old refresh token is presented (replay attempt), the server invalidates the entire token family — triggering re-authentication for the user.

Implement this server-side with a token family table:

token_family: { family_id, current_refresh_token_hash, user_id, created_at, expires_at, revoked }

On each refresh, hash the new token, update current_refresh_token_hash. On replay detection (hash mismatch), set revoked = true for the entire family.

💡
TIP
For Indian B2B SaaS APIs that must comply with RBI's Digital Payment Security Controls, access tokens for payment initiation endpoints should have a maximum TTL of 15 minutes and must be bound to the originating IP or device fingerprint where technically feasible. Refer to RBI Master Direction on Digital Payment Security Controls (2021).

Securing Fintech and B2B APIs in India

Indian fintech APIs operate under specific regulatory frameworks: RBI's Payment Aggregator guidelines, SEBI's cybersecurity circular for registered intermediaries, and the upcoming DPDP Act enforcement (visit /dpdp-compliance for details on personal data protection obligations). These frameworks share common authentication requirements:

  1. Mutual TLS (mTLS) for high-value transaction APIs — both client and server present certificates
  2. Short-lived tokens — 15-minute maximum for payment initiation
  3. Audit logging — every token issuance, refresh, and revocation must be logged with timestamp, IP, and user agent
  4. Scoped access — payment initiation and payment status query must be separate scopes; read scope must not imply write
  5. Rate limiting per token — not just per IP; limit 100 requests per minute per access token
Running a free VAPT scan against your API surface will surface authentication misconfigurations — including JWT validation gaps, missing rate limits, and insecure token handling — before attackers do. Bachao.AI (by Dhisattva AI Pvt Ltd, a DPIIT Recognized Startup) automates this detection across 441 security test cases.

Choosing the Right Scheme: A Decision Framework

    1. Internal microservice-to-microservice calls → Client Credentials OAuth 2.0 or a short-lived signed JWT (service mesh pattern). API keys are acceptable if the environment is fully private and keys are rotated monthly.
    2. Third-party developer API (like Razorpay's API) → API keys with scoped permissions, key-level rate limiting, and a key management dashboard.
    3. Web/mobile app acting on behalf of a logged-in user → Authorization Code + PKCE for issuance; JWT for stateless validation at the API layer; refresh token rotation for session continuity.
    4. Single-page app accessing your own backend → JWT in memory, refresh token in HttpOnly cookie. Never use Implicit flow.
    5. Open Banking / Account Aggregator integration → OAuth 2.0 as specified by the AA Technical Specification. Consent artefacts are JWTs signed with the AA's key. Validate every consent JWT's exp, iss, and consentId.
🎯Key Takeaway
There is no universal winner. API keys are right for server-to-server integrations; OAuth 2.0 is right for user delegation; JWTs are right for stateless scalability. The real risk is not choosing the "wrong" scheme — it is implementing the right scheme incorrectly: API keys in client code, JWTs without expiry, refresh tokens in localStorage, or skipping alg whitelisting. Fix the implementation first.

Frequently Asked Questions

Can I use API keys for a mobile app?
No. Mobile binaries can be decompiled and API keys extracted in minutes. Use OAuth 2.0 Authorization Code flow with PKCE for mobile apps. The API key issued to your mobile app is not secret — treat it as a public client identifier only.
What is the safest way to store JWT tokens in a React app?
Store the access token in a module-level variable or React state (in memory only — it disappears on page refresh). Store the refresh token in an HttpOnly, Secure, SameSite=Strict cookie that the server sets. Never store either in localStorage or sessionStorage, which are accessible to XSS payloads.
What is the difference between OAuth 2.0 and OpenID Connect?
OAuth 2.0 is an authorization framework — it answers "what can this client do?" OpenID Connect (OIDC) is an identity layer on top of OAuth 2.0 — it answers "who is this user?" by adding an ID token (a JWT) to the OAuth flow. If you need login with Google or a corporate SSO, you are using OIDC. If you are issuing API access to a third-party integration, you are using plain OAuth 2.0.
How do I revoke a JWT if it is stateless?
Short TTL (15 minutes) is the primary defense — you only need to tolerate a stolen token for its remaining lifetime. For immediate revocation, maintain a small server-side blocklist of revoked jti (JWT ID) values with a TTL matching the token lifetime. Check the blocklist on every request. This adds one Redis/cache lookup per request — a worthwhile trade for high-value APIs.
Is it safe to put a JWT in a URL query parameter?
No. URLs appear in browser history, server access logs, referrer headers, and analytics tools. A JWT in a query parameter is trivially leaked. Always pass tokens in the Authorization header. If you must use a URL for a one-time link (email verification, password reset), use a short-lived, single-use opaque token, not a JWT.
Do Indian SEBI-registered entities have specific JWT/OAuth requirements?
SEBI's Cybersecurity and Cyber Resilience Framework (CSCRF) for Market Infrastructure Institutions and registered intermediaries mandates strong authentication for system access and API interfaces. It does not prescribe JWT specifically, but requires multi-factor authentication for privileged access, audit trails for all API calls, and periodic access reviews. JWT with short TTL, refresh token rotation, and full audit logging satisfies these controls in practice.
BR

Bachao.AI Research Team

Cybersecurity Research

AI-powered security research and threat intelligence from the Bachao.AI team. Covering the latest vulnerabilities, CVEs, and cybersecurity developments affecting Indian businesses.

Get cybersecurity insights for Indian SMBs

Weekly vulnerability alerts, DPDP compliance tips, and security guides. No spam — unsubscribe anytime.

We respect your privacy. Your email is never shared.

Find out if you're exposed to this class of threat

Free automated scan — risk score in under 2 hours. No credit card required.

Scan Your Attack Surface
Find your vulnerabilitiesStart free scan →