Understand the differences between opaque tokens and JWTs, their use cases, and how they are validated in OIDC-based systems.
In Logto, as an OIDC-based comprehensive CIAM platform, authorization tokens play a crucial role in securing user interactions and managing access to resources. Among the various types of tokens used for authorization, opaque tokens and JWTs (JSON Web Tokens) are the most important.
We've received several questions from our community, such as: What is the difference between an opaque token and a JWT? Why can't I decode the access token I received, and why does the token length seem short? This blog post aims to clarify these concepts and help you understand the distinctions between opaque tokens and JWTs, their use cases, and why you might encounter different behaviors when working with them.
What is an opaque token?
An opaque token is a type of access token that, as the name suggests, is opaque or non-transparent to the client or any external party. This means that the token itself does not carry any readable information about the user or the authorization granted.
When you receive an opaque token, it often appears as a seemingly random string of characters, and attempting to decode it will yield no meaningful data.
Here's an example of an opaque token:
JjVXhOl3UiWBMDdvS3Dt0bFjRlrkNDIsANSrS_7AUGg
Since the actual content of the token is only known to the authorization server that issued it, to validate an opaque token, the client must send it back to the server, which then verifies its authenticity and determines the associated permissions. This approach ensures that sensitive information remains hidden, providing an extra layer of security, but it also requires additional server communication to validate the token.
Pros:
- secure: Opaque tokens do not expose any sensitive information to the client. The token's content is only known to the authorization server.
- revocable: Since the token is stored on the server, and the only way to validate it is through the introspection endpoint on the authorization server, the server can easily revoke the token if needed and prevent unauthorized access.
- small size: Opaque tokens are typically shorter than JWTs, which can be beneficial for performance and storage considerations.
Cons:
- stateful: Opaque tokens require the authorization server to maintain state to validate the token, which can introduce additional complexity and overhead.
- performance: The need for additional server communication to validate the token can impact performance, especially in high-traffic scenarios.
What is a JWT?
In contrast to opaque tokens, a JWT (JSON Web Token) is a self-contained, stateless token that carries information in a structured and readable format.
A JWT is composed of three parts: a header
, a payload
, and a signature
, each encoded in Base64URL.
Here's an example of a JWT:
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c
- The
header
contains information about the type of token and the algorithm used for signing. For example,{"alg": "HS256", "typ": "JWT"}
. - The
payload
section contains claims—pieces of information about the user or the authorization—such as user ID, expiration time, and scopes. Because this data is encoded but not encrypted, anyone who has the token can decode it to see the claims, though they cannot alter it without invalidating the signature. Based on the specification and authorization server configuration, various claims can be included in the payload. This gives the token its self-contained nature. For example,{"sub": "1234567890", "name": "John Doe", "iat": 1516239022}
. - The
signature
is generated by combining the header, payload, and a secret key using the specified algorithm. This signature is used to verify the integrity of the token and ensure that it has not been tampered with.
JWTs are commonly used because they can be verified locally by the client or any service, without needing to interact with the authorization server. This makes JWTs particularly efficient for distributed systems, where multiple services might need to verify the token's authenticity independently.
However, this convenience also comes with the responsibility of ensuring that the token's claims are not excessively exposed, as they are visible to anyone who has access to the token. Also, JWTs are typically short lived, and the expiration time is included in the token's claims to ensure that the token is not valid indefinitely.
Pros:
- stateless: JWTs are self-contained and do not require server-side state to validate.
- cross-service compatibility: JWTs can be easily shared and verified across different services, making them ideal for distributed systems.
- extensible: The payload of a JWT can contain custom claims, allowing for flexible authorization and information sharing.
- standard: JWT tokens follow a well-defined standard (RFC 7519), making them widely supported and interoperable.
Cons:
- exposure: The claims in a JWT are visible to anyone who has access to the token, so sensitive information should not be included in the payload.
- large size: JWTs can be larger than opaque tokens due to the additional information they carry, which can impact performance and storage considerations. The claims in a JWT tokens should be kept to a minimum to reduce the token size.
- revocation complexity: Since JWTs are stateless, they are typically valid for a short period of time, and there is no built-in mechanism for revoking tokens before they expire, meaning that a compromised token may remain valid until it expires.
Opaque access token validation
A opaque access token is validated by sending it back to the authorization server for verification. The authorization server maintains the state of issued tokens and can determine the token's validity based on its internal storage.
- The client requests an access token from the authorization server.
- The authorization server issues an opaque token.
- The client sends the resource access request with the opaque token in the header.
- The resource provider sends a token introspection request to the authorization server to validate the token.
- The authorization server responds with the token information.
JWT access token validation (offline)
A JWT access token can be validated offline by the client or any service that has access to the token's public key.
0.The resource provider pre-fetches the authorization server's public key from the OIDC discovery endpoint. The public key is used to verify the token's signature and ensure its integrity.
1.The client requests an access token from the authorization server.
2.The authorization server issues a JWT token.
3.The client sends the resource access request with the JWT token in the header.
4.The resource provider decodes and validates the JWT token using the public key obtained from the authorization server.
5.The resource provider grants access based on the token's validity.
Use cases in OIDC
In the context of OIDC (OpenID Connect), opaque tokens and JWTs serve different purposes and are used in distinct scenarios.
Opaque tokens
User profile retrieval:
By default, when a client requests an access token without specifying a resource and includes theopenid
scope, the authorization server issues an opaque access token. This token is primarily used to retrieve user profile information from the OIDC/oidc/userinfo
endpoint. Upon receiving a request with the opaque access token, the authorization server checks its internal storage to retrieve the associated authorization information and verifies the token's validity before responding with the user profile details.Refresh token exchange:
Refresh tokens are designed to be exchanged only between the client and the authorization server, without needing to be shared with resource providers. As such, refresh tokens are typically issued as opaque tokens. When the current access token expires, the client can use the opaque refresh token to obtain a new access token, ensuring continuous access without re-authenticating the user.
JWTs
1.ID token:
In OIDC, the ID token is a JWT that contains user information and is used to authenticate the user. Typically issued alongside the access token, the ID token allows the client to verify the user's identity. For example:
// Decoded payload of an ID token
{
"iss": "https://logto.io",
"sub": "1234567890",
"aud": "client_id",
"exp": 1630368000,
"name": "John Doe",
"email": "john.doe@mail.com",
"picture": "https://example.com/johndoe.jpg"
}
The client can validate the ID token to ensure the user's identity and extract user information for personalization or authorization purposes. ID token is for one-time use only and should not be used for API resource authorization.
2.API resource access:
When a client requests an access token with a specific resource indicator, the authorization server issues a JWT access token intended for accessing that resource. The JWT contains claims that the resource provider can use to authorize the client's access. For example:
// Decoded payload of a JWT access token
{
"iss": "https://dev.logto.app",
"sub": "1234567890",
"aud": "https://api.example.com",
"scope": "read write",
"exp": 1630368000
}
The resource provider can validate the request by checking the claims:
-
iss
: Confirms the token was issued by a trusted authorization server. -
sub:
Identifies the user associated with the token. -
aud
: Ensures the token is intended for the specific resource. -
scope
: Verifies the permissions granted to the user.
Conclusion
In summary, opaque tokens and JWTs serve different purposes in OIDC-based systems, with opaque tokens providing a secure and stateful approach to authorization and JWTs offering a self-contained and stateless alternative. Understanding the distinctions between these token types and their use cases is essential for designing secure and efficient authentication and authorization mechanisms in your applications.
Discover more access token features in Logto:
Top comments (0)