OAuth 2.0 and OpenID in simple terms

iamprovidence
24 min readJul 7, 2024

--

Have you ever found yourself in a situation when you want to learn OAuth 2.0, but the information you find online is so obscure and confusing that you just give up? Guess what, that is how everybody feels 😂. Most of the articles assume you already know what OAuth is. They abuse all those complex academic terminology nobodies understand. But not me. I would not do that to you 🙃.

OAuth and OpenId do not have to be complex. This is why, in today’s article we will see what OAuth is. The roles it defines. Difference between Front channel and Back channel. What type of clients exist and which authentication flow should be used. I will answer the question “What OpenId has to do with all that”. But most importantly, you will obtain comprehensive knowledge, up to the point that any other article about OAuth will start making sense 😎.

The subject is quite advanced. Make sure you have read previous articles about authentication:

You can also investigate more practical stories about how to implement authentication in C# environment:

Do not forget to check out some other related articles:

  • What is authentication schema in ASP about?
  • Authorization policy under the hood
  • Encapsulate authentication with DelegatingHandler
  • How to parse token on client side

Meanwhile we are starting.

What OAuth 2.0 and OpenId Connect are?

You may heard of OAuth 2.0 and OpenId before. It often happens that, those two terms are used together. However, when trying to learn about them, you can find a complex explanation:

OAuth 2.0 (Open Authorization 2.0) is an authorization framework that enables third-party services to access resources on behalf of a user without the need to expose their credentials (such as passwords)

The staff is not better for OpenID either:

OIDC (OpenID Connect) is an open standard and decentralized authentication protocol that allows users to log in to multiple unrelated websites without having to have a separate identity and password for each (Single Sign-On)

While those are technically correct, they often confuse and prevent a curious developer from learning more 😒.

Let’s s simplify those terminology and make it more human-friendly:

OAuth 2.0 is an authorization framework

OpenId is just 10% on top of OAuth 2.0 to do an authentication

Where:

Authorization (AuthZ) — is the process of defining what permissions a user has

Authentication (AuthN) — is the process of defining who a user is

Are you still confused😁? Let’s simplify it even more.

If you have been following me before, you know how hard it is to implement authentication and authorization on the project. You want to use cookies, but those kids with their fancy-schmancy React cannot use cookies. Then you also need something for mobile and desktop apps. Later you want to integrate with other systems and so on…😑

This is exactly what OAuth tries to solve. It provides a standard authentication approach that can be used in different projects. Having standard das ist gut. It encourages to write generic code and reuse it.

Let’s try to come up with an understandable definition one more time:

OAuth2.0 and OpenID are just a set of algorithms, that provide a common language and structure for implementing authentication and authorization across different platforms

I hope this time it was clearer and we can start to learn how they work🙃

Roles

Before implementing actual authorization, you should understand what roles OAuth defines.

First of all, you have a resource owner. Somebody, who wants to get access to his data (resource) on the Internet.

Of course, the data do not exist on its own. There is a server hosting it, which is called a resource server.

Our resource owner also needs a way to access the Internet. It is done by the client. An application that makes requests to the protected resource on behalf of the resource owner.

However, we are still missing the most crucial part — authorization. We cannot just get any resource from any user. First, we need to log in to the system. This is done in an authorization server. This server is responsible for authorizing the resource owner. It issues an access token to the client that can be used to obtain the resource from the resource server.

There you have it. All OAuth roles:

  • resource owner
  • resource server
  • client
  • authorization server

A few things to notice:

  • a resource owner is usually a user, but it also can be a server
  • the authorization server may be a separate server or the same server as the resource server
  • the access token can be an opaque token or a self-contained token like JWT. The thing is, the client should not care about it, and should not try to parse it

As you can see from the image above, there are two separate flows:

  • authorization flow, when the client obtains an access token
  • accessing protected resources flow, when the client obtains resource

We will discuss them later.

In case you still struggle to understand those roles, I have a more practical example.

Imagine you are a developer at Google. You need to write a Calendar app.

For that, you decided to use Vue.js. This is our client application while resource owners are just regular users.

Sure you need an API to fetch data. You can also call it a resource server.

The last missing part is security. But don’t worry. Google is a large company with tons of applications. They already have an authorization server. We just need to get an access token from it.

Now imagine yourself in the role of a regular user. If you want to access your Google Calendar, first you need to log in.

Therefore you will press the “Sign in with Google” button.

It will redirect you from our client app to the authorization server where the log-in form is.

After you enter your email and password, the authorization server redirects you back to our client application and issues an access token. Which now can be used to fetch events from Calendar API.

As you can see OAuth is not as complicated as it looks, it is pretty much what we are used to 🙃.

Client Types

Let’s continue our journey.

As was mentioned before, OAuth defines 4 roles:

  • resource owner
  • resource server
  • client
  • authorization server

We are interested in the client, an application that users use.

It is important to understand that there are two types of clients:

  • public — clients that cannot securely store credentials
    - native (mobile/desktop/console) applications
    - SPA web applications running in a web browser
  • confidential — clients that can securely store credentials
    - MPA web application running on a web server
    - API server

You will see later how OAuth works differently based on the client type.

Client Registration

Before using OAuth, the client application should be registered in the authorization server.

Typically this involves setting up a developer account at the authorization service, then answering some questions about your application, uploading a logo, etc.

However, for simplicity, let’s just say that our authorization server defines a static list of clients in the code:

public class AuthorizationServerConfiguration
{
. . .

public static List<Client> GetClients()
{
var mvcApp = new Client
{
ClientId = "my-client-id",
ClientSecret = "H57G0S2Lhr",

RedirectionEndpoints = new string[]
{
"https://localhost:7066/oauth-complete",
"https://staging.client.com/oauth-complete",
"https://production.client.com/oauth-complete",
},
AllowedScopes = new string[]
{
"calendar-events",
"photos",
"mails",
},
};

return new List<Client> { mvcApp };
}
}

The registered client has the following properties:

  • ClientId — unique client identifier (you can think of it as a login for a client app)
  • ClientSecret — a piece of sensitive information that only the client and the authorization server should know (you can think of it as a password for a client app)
  • RedirectionEndpoint — an optional client URL, used by the authorization server to redirect the resource owner back to the client (multiple URLs can be defined)
  • AllowedScopes — basically permissions that can be granted in the issued access token. The client may request all scopes or less, but not more than defined

Authorization server endpoints

Another mandatory requirement for OAuth to work says that the authorization server should implement two endpoints:

  • Authorization endpoint (HTTP GET) —an endpoint that displays a login form where the resource owner will enter his login and password
  • Token endpoint (HTTP POST) — used by the client application to get an access token

Do not worry if you don’t understand. And do not try to remember everything. You will see how those endpoints are used later. Just know that those endpoints should obey standards.

The authorization endpoint has one required parameter:

  • response_type — determines what data should be returned from the authorization endpoint (can be code or token)

The token endpoint also has one required parameter:

  • grant_type — determines which authorization algorithm is used to get the access token (authorization_code, password, client_credentials, refresh_token, etc)

Be aware:

  • there are other endpoints, but only those two are important
  • it is not mandatory to use both endpoints. Sometimes only one will be used

Front Channel vs Back Channel

The last terms we will learn are “front channel” and “back channel”.

The authorization endpoint is a GET endpoint. The resource owner is redirected from our client to the authorization server where he sees the login form. After the user enters his email and password, the authorization server redirects him back to our client.

With all those redirections the only way to send data between the client and the authorization server is URL’s parameters. And often all this happens in the browser.

Front Channel — is a communication channel between the browser and the authorization server.

Even though we are using HTTPS, this communication is not considered secure, because of browser vulnerabilities. Somebody can see GET requests in the browser history, in the Network tab, install malicious software that will track those requests, or just simply look over your shoulder at what you have in the URL bar 😬.

On the other hand, a Token endpoint is a POST endpoint that no longer requires user interaction. Therefore we can just send a POST request with parameters in its body and receive a response.

Back Channel — is a communication channel between the client and the authorization server without a browser.

It is considered to be secure.

Notice, that it is still possible to have back channel interaction for the Authorization endpoint or front channel interaction for the Token endpoint. The described example above is just the usual way of working.

Authorization flows

Phew😮‍💨. I think this is all the preparation we have to make to finally use OAuth. Don’t worry if those still make no sense to you. You will see how it works altogether. Let’s recap what we have already learned:

  • roles (resource owner, resource server, client, authorization server)
  • client types (public, confidential)
  • client needs to be registered in the authorization server
  • authorization server has to implement at least 2 endpoints (authorization endpoint, token endpoint)
  • there are two types of communication (front channel, back channel)

Now, when everything is set up, it is finally time for OAuth.

As was mentioned before, OAuth is just a bunch of algorithms to get an access token. Those algorithms are called authorization flows. They focus on communication between the client and the authorization server and allow the client to obtain the access token.

Those flows are:

  • password flow (legacy)
  • implicit flow (legacy)
  • code flow
  • PKCE flow
  • refresh token flow
  • client credentials flow

Let’s see them one by one.

Password flow (legacy)

The most simple flow that can be used by any client is Password flow. It allows a client to receive an access token directly from the Token endpoint:

  1. To use this flow the client application should display a login form and collect the user’s credentials. Then the client sends a POST request to the authorization server’s Token endpoint.

In the request, we have the following parameters:
- grant_type=password — indicates that your client wants to use password flow
- registered client app information (client_id, client_secret)
- resource owner’s credentials (username, password)
- scope, which permissions the client wants to have in the access token

Content-Type: application/x-www-form-urlencoded // format is important!

HTTP POST: https://authorization-server.com/services/oauth2/token // {Token Endpoint}

grant_type=password& // required
client_id={ClientID}& // required
client_secret={ClientSecret}& // required if client is confidential
username={User login}& // required
password={Password}& // required
scope={Scopes} // optional

2. The authorization server validates that the client with such ClientId and ClientSecret is registered. Then it makes sure that scope is allowed for this client. For the final, it verifies that the user’s credentials are correct.

In the end, the authorization server issues an access token in the response:

{
"access_token": "{Access Token}", // always included
"token_type": "{Token Type}", // always included
"expires_in": {Lifetime In Seconds}, // optional
"refresh_token": "{Refresh Token}", // optional
"scope": "{Scopes}" // included if the granted scopes differ from the requested ones
}

Or an error response, in case something went wrong:

{
"error": "{Error Code}", // required
"error_description": "{Error Description}" // optional
}

Key points to notice:

  • in step 1, the client makes a token request. Even though it is a POST request, parameters are sent in the application/x-www-form-urlencoded format and not in the body. This is crucial
  • in step 1, the client_secret parameter is only required if the client is confidential
  • in step 2, refresh_token is optional in the response. Some authorization servers will always return it, some only on first authorization, others require refresh_token or offline_access parameter to be present in authorization request scopes or as a query parameter. The behavior of a refresh token should be specified in the authorization server documentation
  • the flow is considered to be obsolete
    - the client application can collect the user’s password. Therefore the flow is only recommended for the first-party application
  • it can be used to migrate existing clients that still use username/ password authentication (like HTTP Basic) to OAuth by converting the stored credentials to an access token

Implicit flow (legacy)

Implicit flow was initially designed for public clients (native apps or JavaScript-based website running in a browser). Even though it is outdated, it is still important to know about its existence, since some legacy systems may use it:

  1. First, we redirect the user from our website to the authorization endpoint.

The query parameters are:
- response_type=token indicates that your client expects to receive an access token
- registered client app information (client_id)
- redirect_uri a URL of the client, so the authorization server can redirect us back
- scope, which permissions the client wants to have in the access token
- state, an arbitrary string that the authorization server will send us back

HTTP GET: https://authorization-server.com/oauth2/authorize? // {Authorization Endpoint}
response_type=token& // required
client_id={ClientID}& // required
redirect_uri={Redirect URI}& // required if client registered with multiple redirection endpoint
scope={Scopes}& // optional
state={Arbitrary String} // optional

2. The authorization server checks whether the client with ClientId is registered. Then it makes sure that scope is allowed for this client. If so, a login form is displayed.

In this form, the resource owner will see what scopes (permissions) the client will receive. If the user agrees with those, he enters his login and password.

3. After the resource owner grants access, the authorization server redirects the user back to the client and issues an access token:

HTTP GET: {Redirect URI}?
access_token={Access Token}& // always included
token_type={Token Type}& // always included
expires_in={Lifetime In Seconds}& // optional
scope={Scope}& // included if the granted scopes differ from the requested ones
state={Arbitrary String} // included if the authorization request included 'state'

Or an error response:

HTTP GET: {Redirect URI}?
error={Error Code}& // required
error_description={Error Description}& // optional
state={Arbitrary String} // included if the authorization request included 'state'

A few important things about this flow:

  • in step 1, the client_secret parameter is missing because public clients cannot store secrets safely
  • in step 1, the state parameter is an arbitrary string that is returned in the response of step 3. The most common use cases for this parameter are:
    - to avoid CSRF attack
    - to persist the application’s state between redirects (e.g. you have pagination, a user is at page 5, the authorization process is initiated, you serialize the current application’s state to the state parameter, pass it to the authorization server, and after authorization is done, you will receive a state back, deserialize it, and restore pagination)
  • the flow is considered to be obsolete
    - access token is returned as an HTTP GET query parameter via the front channel and is exposed in the browser history. It could be accessible through browser logs or other vulnerabilities
    - because of front channel communication this flow does not issue a refresh token. Meaning users will be forced to authenticate often. This is a security measure. This way intruders can only steal a short-lived access token, but not a refresh, which gives unlimited lifetime

I think you understand why it is marked as a legacy 😅. You will see a bit later which flow should be used for public clients instead of this one. Right now it is time for a Code flow.

Code flow

If your client is a confidential website on a server (MPA) you should use code flow:

  1. First, we redirect the user from our website to the authorization endpoint in the authorization server.

It is important to have a parameter with a value response_type=code. It indicates that your client expects to receive an authorization code:

HTTP GET: https://authorization-server.com/oauth2/authorize? // {Authorization Endpoint}
response_type=code& // required
client_id={ClientID}& // required
redirect_uri={Redirect URI}& // required if client registered with multiple redirection endpoint
scope={Scopes}& // optional
state={Arbitrary String} // optional

2. The authorization server figures out what client it is based on ClientId. Displays a login form. In this form, the resource owner will see what scopes the client will receive. If the user agrees with those, he enters his login and password.

3. After the resource owner grants access, the authorization server redirects the user-agent back to the client app. In the response, the client receives a special code that will be used in the next step:

HTTP GET: {Redirect URI}?
code={Authorization Code}& // always included
state={Arbitrary String} // included if the authorization request included 'state'

4. The client requests an access token from the token endpoint.

In the request, we have the following parameters:
- grant_type=authorization_code — indicates that the client wants to use Code flow
- client information (client_id, client_secret)
- authorization code received in the previous step

Content-Type: application/x-www-form-urlencoded // format is important!

HTTP POST: https://authorization-server.com/services/oauth2/token // {Token Endpoint}

grant_type=authorization_code& // required
client_id={ClientID}& // required
client_secret={ClientSecret}& // required
code={Authorization Code}& // required
redirect_uri={Redirect URI} // required if the authorization request included 'redirect_uri'

5. The authorization server validates the authorization code and issues an access token in the response:

{
"access_token": "{Access Token}", // always included
"token_type": "{Token Type}", // always included
"expires_in": {Lifetime In Seconds}, // optional
"refresh_token": "{Refresh Token}", // optional
"scope": "{Scopes}" // included if the granted scopes differ from the requested ones
}

There are a few important things:

  • in step 3, the authorization server can only respond to the client with an HTTP GET redirect request. Sending sensitive data via the front channel is not secure. Therefore, it does not issue an access token directly, but code
  • in step 4, the issued authorization code is just a random, short-lived value. It can only be used once. The code than exchanged with HTTP POST request. This adds a layer of security reducing the risk of interception and misuse
  • in step 4, the client sends ClientSecret through a secure back-channel communication. This flow cannot be used with public clients, because you cannot store securely ClientSecret on those or use back-channel communication

You can find an example of how a code flow can be implemented with Identity Server and ASP.Net MVC here.

PKCE flow

PKCE (Proof Key for Code Exchange) is an extension to the Code flow, designed to be used with public clients (native apps or JS-based websites). This flow is the replacement for the Implicit one:

  1. First, the client application should create a codeVerifier and a codeChallenge:
var codeVerifier = "A9nnMidwx1aQiu"; // a cryptographically random string

var codeChallenge = sha256(codeVerifier); // hash of codeVerifier

2. Then we redirect the user from our website to the Authorization endpoint in the authorization server with response_type=code, code_challenge, and the name of the hash function used to create code challenge (code_challenge_method):

HTTP GET: https://authorization-server.com/oauth2/authorize? // {Authorization Endpoint}
response_type=code& // required
client_id={ClientID}& // required
redirect_uri={Redirect URI}& // required if client registered with multiple redirection endpoint
scope={Scopes}& // optional
state={Arbitrary String}& // optional
code_challenge={Code Challenge}& // required
code_challenge_method=S256 // required

3. The authorization server figures out what client it is based on ClientId. Displays a login form. In this form, the resource owner will see what scopes the client will receive. If the user agrees with those, he enters his login and password.

4. After the resource owner grants access, the authorization server redirects the user-agent back to the client issuing code:

HTTP GET: {Redirect URI}?
code={Authorization Code}& // always included
state={Arbitrary String} // included if the authorization request included 'state'

5. The client requests an access token from the authorization server’s Token endpoint. In the request grant_type=authorization_code, code_verifier, and code are included:

Content-Type: application/x-www-form-urlencoded // format is important!

HTTP POST: https://authorization-server.com/services/oauth2/token // {Token Endpoint}

grant_type=authorization_code& // required
client_id={ClientID}& // required
code={Authorization Code}& // required
code_verifier={Code Verifier}& // required
redirect_uri={Redirect URI} // required if the authorization request included 'redirect_uri'

6. The authorization server validates the authorization code, creates its own code challenge from code_verifier, and compares it to the one received in step 2.

At the end, the access token is issued in the response:

{
"access_token": "{Access Token}", // always included
"token_type": "{Token Type}", // always included
"expires_in": {Lifetime In Seconds}, // optional
"refresh_token": "{Refresh Token}", // optional
"scope": "{Scopes}" // included if the granted scopes differ from the requested ones
}

Worth to mention:

  • this flow is the replacement for legacy Implicit flow
  • this flow allows clients to get an access token without sending ClientSecret, making it secure for public clients
  • this flow can be used with confidential clients too
  • this flow relies on a hash function, which is irreversible. If the intruder intercepts code_challenge via the front channel in step 2, he cannot compute code_verifier and won’t be able to obtain an access token
  • code_verifier is sent via a secure back channel
  • PKCE parameters provide CSRF protection, so the state is used only to restore the application state after redirects

People usually struggle to understand how this flow can be used with native applications like mobile apps, desktops, consoles, etc:

  • in step 2, native apps should open a web browser for a user to enter his credentials
  • additionally, they should listen for a URL callback to launch the native app back in step 4

You can find some C# examples here.

Refresh token flow

This flow allows to exchange a refresh token for a new access token, without user interaction.

To use this flow, you should already obtain a refresh token with one of the flows from above.

  1. The client requests an access token from the authorization server’s Token endpoint. In the request grant_type=refresh_token and previously obtained refresh token are present:
Content-Type: application/x-www-form-urlencoded // format is important!

HTTP POST: https://authorization-server.com/services/oauth2/token // {Token Endpoint}

grant_type=refresh_token& // required
client_id={ClientID}& // required
client_secret={ClientSecret}& // required if client is confidential
refresh_token={Refresh Token}& // required
scope={scopes} // optional

2. The authorization server validates the refresh token and issues the access token in the response:

{
"access_token": "{Access Token}", // always included
"token_type": "{Token Type}", // always included
"expires_in": {Lifetime In Seconds}, // optional
"refresh_token": "{Refresh Token}", // optional
"scope": "{Scopes}" // included if the granted scopes differ from the requested ones
}

Keep in mind:

  • in step 1, the client can send scope parameters that allow to request an access token with different scopes
  • in step 2, the authorization server may issue a new refresh token and invalidate the current one

Client credentials flow

The last flow is suitable in case the resource owner is not a user, but a server (confidential API server):

  1. The client requests an access token from the authorization server’s Token endpoint. In the request grant_type=client_credentials:
Content-Type: application/x-www-form-urlencoded // format is important!

HTTP POST: https://authorization-server.com/services/oauth2/token // {Token Endpoint}

grant_type=client_credentials& // required
client_id={ClientID}& // required
client_secret={ClientSecret}& // required
scope={Scopes} // optional

2. The authorization server issues an access token in the response:

{
"access_token": "{Access Token}", // always included
"token_type": "{Token Type}", // always included
"expires_in": {Lifetime In Seconds}, // optional
"scope": "{Scopes}" // included if the granted scopes differ from the requested ones
}

Notice:

  • there is no refresh token since communication is completely on the back channel and the intruder cannot steal an access token in any way
  • to refresh an access token, the client just requests a new token in the same way
  • limited token’s lifetime is still useful to refresh scopes and enhance security

Which flow should I use? 🤔

There were times when I would follow a decision tree to use the correct flow:

However, nowadays, I don’t see why wouldn’t you always use Code flow with PKCE extension for any client type that requires user interaction😅.

Accessing protected resources flow

The second part of OAuth 2.0 implies getting resources from the resource server using the access token through one of the authorization flows above.

Nothing complicated here. The client accesses protected resources with a Bearer schema. Each HTTP request includes the Authorization header with the word “Bearer” and the access token:

HTTP: https://resource-server.com/get-resource

Authorization: Bearer <access_token>

And that, kids, is OAuth 2.0 in simple terms for you 😅
Oh, sh💩t, I forgot. We also have OpenId 😒.

OpenId Connect

If you get to this point, you may be thinking:

I’m already tired 😫. When the heck this guy will start talking about OpendId? 🤔

Don’t worry. Even though OpenId is a separate thing, it is built upon OAuth. If you know OAuth, you know 90% of OpenId.

Using OAuth the client application can obtain an access token, but it has no way to know information about the current user. This is exactly what OpenId Connect is for.

While OAuth 2.0 is a specification about how to issue access tokens.
OpenID Connect is a specification about how to issue ID tokens.

ID Token vs Access Token

I hope you have read my article about tokens, where I also discuss Access and ID tokens 🙃. If not, let me remind you key differences between those two:

  • The access token is for authorization. The ID token is for authentication.
  • The access token contains permission. The ID token contains the user’s information.
  • The access token may be a reference or a self-contained token. The ID token is always self-contained JWT token.
  • The access token is used to request protected API. The ID token should never be sent to the API.
  • The access token should never be parsed and used by the client. The ID token should be parsed and used by the client application to get the user’s information.

Authorization server endpoints

As was mentioned before, the authorization server has 2 endpoints:

  • Authorization endpoint
  • Token endpoint

The Authorization endpoint has one required parameter:

  • response_type — determines what data can be returned from the authorization endpoint

For OAuth response_type can be code or token.
But OpenId allows code, token, id_token, or any combination of those.

Authentication flows

All the flows that we have discussed also work in OpenId.

In addition, OpenId adds a few more. If you want to use them, you need to include openid scope in the requests.

Implicit flow

Similarly to OAuth, you can use Implicit flow in the OpenId.

When the value of response_type in step 1 is id_token, an ID token is issued from the authorization endpoint.

In case response_type is token and id_token, an access and ID token are issued.

Code flow

In the code flow, an ID token will be issued along with access and refresh tokens.

Hybrid flow

Hybrid flow is a combination of Code flow and Implicit flow. In this case Authorization endpoint, in step 1, returns not only code but also a token.

When response_type is code token authorization endpoint issues code and access token:

When response_type is code id_token the authorization endpoint issues code and ID token:

When response_type is code token id_token authorization endpoint issue code, access, and ID tokens:

As you see, both the authorization endpoint and the token endpoint issue tokens, but the contents of the tokens are not always the same.

The Hybrid flow is beneficial for scenarios where certain tokens are needed immediately on the client side, and it is commonly used in situations where both authentication and authorization are required.

Remember that you can also use the PKCE extension to obtain tokens for public clients.

And that, kids, is OpenId Connect in simple terms for you 😅

Useful resources

For the end, I just want to share with you some resources I find useful:

Specifications for OAuth 2.0 can be found here.
Specifications for OpenId can be found here.

You can find the OAuth 2.0 playground here. It will allow you to experience each flow without writing any code!

This one allows you to create an authorization server, where you can register clients, add users, etc. It can be helpful if you want to try OAuth as a client only, test SSO locally, play with other authentication protocols, etc.

The authorization server can be debugged with OAuth 2.0 debugger or OpenId Connect debugger.

Also, I found this resource useful to read about other authorization server endpoints. Pay attention to /.well-known/openid-configuration server discovery endpoint. It will return information about the authorization server, like token endpoint URL, supported parameters for response_type, etc. For example, this is what Google Auth well-known endpoint returns.

A comprehensive compilation of all diagrams illustrating the OpenID Connect flows can be found here. Give this guy a clap. It is totally deserved.

The beauty of OAuth and OpenId is that you don’t have to implement it every time from scratch. It is likely there is already a library/ framework/ package that did it for you. In case you are a C# dev, do not forget to check out IdentityServer and IdentityModel.

Let me know, if you have any other links to share😉.

Last Words

And that, kids, is OAuth 2.0 and OpenId Connect in simple terms for you 😅. This time for sure 😂. Maybe that was not as simple as I expected it to be at the beginning, but I did my best 😒.

If you feel sick and want to take a day off at work, go for it. That’s how everybody feels after reading about OAuth 🤕.

Don’t worry if the subject still looks confusing to you. I am pretty sure even guys who created OAuth are also still confused 😬. After all, it is pretty advanced security stuff. However, once you learn it, you will be finally among the chosen ones who can brag around they understand OAuth😎.

You can also try to read this article one more time.

Or even more than once 🙃. It is totally normal to miss stuff at first. You will get better the more you practice it. Even though I have shown examples of OAuth for first-party applications, it is often used for integration with other systems like Google, Microsoft, Amazon, etc. Try to create a small pet project where you connect to GMail or something using OAuth.

There is a lot of other stuff I have not mentioned, but I am convinced that at this point you are already exhausted, so let’s do our usual and call it a day.

👏 Claps if you enjoyed this article

💬 Let me know how many times you tried to learn OAuth. For me, it was definitely over dozens

☕️ You can support me with a coffee using the link below

✅ And don’t forget to follow not to miss future articles

😉 See ya

--

--

iamprovidence

👨🏼‍💻 Full Stack Dev writing about software architecture, patterns and other programming stuff https://www.buymeacoffee.com/iamprovidence