Why you should use authorization code flow instead of implicit flow?

In this article, we introduced the implicit flow and authorization code flow within the OAuth 2.0 protocol, explaining the security vulnerabilities present in the implicit flow and how the authorization code flow (along with PKCE) addresses these issues.
Darcy Ye
Darcy YeDeveloper
January 03, 20246 min read
Why you should use authorization code flow instead of implicit flow?

Authorization code flow and implicit flow are grant types of OAuth 2.0 protocol. They are used to get an access token from an authorization server. With access tokens, applications or services can perform certain operations and access specific resources on behalf of users.

What is OAuth?

When we talk about OAuth, we usually refer to OAuth 2.0, known as "Open Authorization", is an established protocol enabling websites or applications to utilize resources from other web services on a user's behalf. It succeeded OAuth 1.0 in 2012 and has since become the widely accepted standard for digital authorization. OAuth 2.0 facilitates controlled access, allowing client applications specific permissions to interact with resources representing the user, all without revealing the user's login details.

Although primarily utilized in web environments, OAuth 2.0's framework also extends to various client forms. This includes browser-based apps, server-side web applications, native or mobile applications, and even interconnected devices, detailing the approach for managing delegated access across these platforms.

OAuth 2.0 protocol defines four primary grant types, each designed for different scenarios:

  • Authorization code: Ideal for server-side applications, this flow involves redirecting the user to the authorization server to sign in. Once authenticated, the user is redirected back to the application with an authorization code, which is then exchanged for an access token.
  • Implicit: Suited for client-side or browser-based applications (like single-page applications), where the access token is returned immediately without an extra authorization code exchange step.
  • Resource owner password credentials: This type allows the client application to directly request and receive an access token by submitting the user's credentials (username and password). It’s less common due to security concerns and usually used with highly trusted applications.
  • Client credentials: Used for server-to-server communication where the application itself is the client. It involves the application authenticating with the authorization server and requesting an access token to access its own resources or those of another service.

Let’s take a look at two commonly used grant types, authorization code grant flow and implicit grant flow since many developers are unsure about which grant type to choose.

How implicit flow works?

Resource ServerAuthorization ServerClientUserResource ServerAuthorization ServerClientUserAccess applicationRedirect to AS for authenticationAuthenticate and approve accessAccess token in URL fragmentRedirect with access token in URLRequest resource with access tokenResource data

The implicit flow in OAuth 2.0 was developed about a decade ago, a time when browser functionalities were quite different from today. This flow emerged mainly due to historical browser limitations where JavaScript could only send requests to the server from which the page was loaded. The standard OAuth authorization code flow, however, necessitates a POST request to the token endpoint of the OAuth server, typically hosted on a different domain than the application. This restriction made it impossible to implement this flow purely in JavaScript. The implicit flow avoided this by eliminating the POST request, instead delivering the access token directly in the redirection process.

Nowadays, with the widespread adoption of Cross-Origin Resource Sharing (CORS) in browsers, the constraints that led to the Implicit flow’s creation are no longer relevant. CORS allows JavaScript to make requests to different domain servers, provided they permit such actions. This advancement makes the authorization code flow viable for use in JavaScript applications.

It’s important to recognize that the Implicit flow has always been considered a less secure alternative to the authorization code flow. For instance, the OAuth specification doesn’t support the return of refresh tokens in the implicit flow due to security concerns.

How authorization code flow works?

Resource ServerAuthorization ServerClientUserResource ServerAuthorization ServerClientUserAccess applicationRedirect to AS for authenticationAuthenticate and approve accessAuthorization codeRedirect with authorization codeExchange code for access tokenAccess tokenRequest resource with access tokenResource data

Now, it's possible to use the authorization code flow from browsers, but we still need to address a concern with JavaScript applications. Traditionally, the authorization code flow uses a client secret to exchange an authorization code for an access token, which cannot be included in JavaScript applications while keeping it secret.

This issue has been resolved by the Proof Key for Code Exchange (PKCE) extension (read this blog to know more details about PKCE and how can it protect authentication flow). The authorization code flow with PKCE adds extra steps, allowing us to secure the authorization code, making it useless even if it gets stolen during the redirection process.

Disadvantages of implicit flow

From the introduction above, we can see two significant security risks associated with the implicit flow:

  1. One reason the implicit flow is less secure than the authorization code flow is the lack of client authentication. Unlike confidential clients, public clients such as JavaScript applications running in a browser cannot protect any secrets. Therefore, requiring public clients to authenticate makes no sense, as the client credentials can be seen by inspecting the source code in the browser. In cases where no client authentication is required, any application can pretend to be that client, as long as it knows the client's id.
  2. The implicit flow must pass the access token via URL redirection, making other types of attacks possible. For example, if the token is in the query part of the URL, the browser cannot prevent accidentally saving the access token to the history. Moreover, nothing can stop the full URL containing the token from being sent to other servers.

Can authorization code flow eliminate the security issues of implicit flow?

The answer is YES:

  1. The authorization code flow uses the authorization code obtained through user authentication along with client credentials to retrieve the access token via token requests, a process protected by HTTPS connection encryption.
  2. As mentioned earlier, by introducing the PKCE mechanism, we can ensure that even if malicious applications or parties intercept the authorization code and client credentials, they cannot obtain the access token, because they do not have the correct code verifier.

If you're currently using the implicit flow in your business, switching to the authorization code flow with PKCE can provide better security for both you and your users. We understand that migrating and managing an identity system can be cumbersome and costly, so we built Logto - a simple, easy-to-use, yet powerful identity management tool. Logto utilizes the authorization code flow integrated with PKCE in the user login process, offering the highest level of security for users.