<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>Forem: Auth0 Ambassadors</title>
    <description>The latest articles on Forem by Auth0 Ambassadors (@auth0ambassadors).</description>
    <link>https://forem.com/auth0ambassadors</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Forganization%2Fprofile_image%2F2583%2Fe6f0cba6-886e-4ea8-9b86-4219f059d08f.jpg</url>
      <title>Forem: Auth0 Ambassadors</title>
      <link>https://forem.com/auth0ambassadors</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://forem.com/feed/auth0ambassadors"/>
    <language>en</language>
    <item>
      <title>Authorization and Authentication for Everyone</title>
      <dc:creator>Kim Maida</dc:creator>
      <pubDate>Mon, 20 Jul 2020 16:16:49 +0000</pubDate>
      <link>https://forem.com/auth0ambassadors/authorization-and-authentication-for-everyone-4ol8</link>
      <guid>https://forem.com/auth0ambassadors/authorization-and-authentication-for-everyone-4ol8</guid>
      <description>&lt;p&gt;Authentication and authorization are necessary for many of the applications we build. Maybe you've developed apps and implemented authentication and authorization in them — possibly by importing a third party auth library or by using an identity platform.&lt;/p&gt;

&lt;p&gt;Maybe you got the job done, but you really weren't clear on &lt;em&gt;what&lt;/em&gt; was happening behind the scenes, or &lt;em&gt;why&lt;/em&gt; things were being done a certain way. If you'd like to build a foundational understanding of what goes on behind the scenes when using OAuth 2.0 and OpenID Connect standards, read on!&lt;/p&gt;




&lt;p&gt;&lt;strong&gt;&lt;em&gt;Authentication is hard.&lt;/em&gt;&lt;/strong&gt; Why is this? Auth standards are well defined — but challenging to get right. And that's okay! We're going to go through it in an approachable way. We'll address the &lt;strong&gt;concepts of identity step by step, building on our knowledge as we go along.&lt;/strong&gt; By the time we're done, you should have a foundation and know where you might want to dig deeper.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;This post is meant to be read from beginning to end. We'll build on top of each concept to layer knowledge when it makes sense to introduce new topics. Please keep that in mind if you're jumping around in the content.&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;ul&gt;
&lt;li&gt;Introduction&lt;/li&gt;
&lt;li&gt;OAuth 2.0&lt;/li&gt;
&lt;li&gt;The Login Problem&lt;/li&gt;
&lt;li&gt;OpenID Connect&lt;/li&gt;
&lt;li&gt;Authentication with ID Tokens&lt;/li&gt;
&lt;li&gt;Accessing APIs with Access Tokens&lt;/li&gt;
&lt;li&gt;Delegation with Scopes&lt;/li&gt;
&lt;li&gt;Resources and What's Next?&lt;/li&gt;
&lt;/ul&gt;




&lt;h1&gt;
  
  
  Introduction
&lt;/h1&gt;

&lt;p&gt;When I told family or friends that I "work in identity," they often assumed that meant I was employed by the government issuing driver's licenses, or that I helped people resolve credit card fraud.&lt;/p&gt;

&lt;p&gt;However, neither were true. I &lt;a href="https://auth0.com" rel="noopener noreferrer"&gt;formerly worked for Auth0&lt;/a&gt;, a company that manages &lt;em&gt;digital identity&lt;/em&gt;. (I'm now a member of the &lt;a href="https://auth0.com/ambassador-program" rel="noopener noreferrer"&gt;Auth0 Ambassadors program&lt;/a&gt;, and a &lt;a href="https://developers.google.com/" rel="noopener noreferrer"&gt;Google Developer Expert&lt;/a&gt; in SPPI: Security, Privacy, Payments, and Identity.)&lt;/p&gt;

&lt;h3&gt;
  
  
  Digital Identity
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Digital identity&lt;/strong&gt; refers to a set of attributes that define an individual user in the context of a function delivered by a particular application.&lt;/p&gt;

&lt;p&gt;What does that mean?&lt;/p&gt;

&lt;p&gt;Say you run an online shoe retail company. The &lt;em&gt;digital identity&lt;/em&gt; of your app's users might be their credit card number, shipping address, and purchase history. Their digital identity is contextual to &lt;em&gt;your&lt;/em&gt; app.&lt;/p&gt;

&lt;p&gt;This leads us to...&lt;/p&gt;

&lt;h3&gt;
  
  
  Authentication
&lt;/h3&gt;

&lt;p&gt;In a broad sense, &lt;strong&gt;authentication&lt;/strong&gt; refers to the process of verifying that a user is who they say they are. &lt;/p&gt;

&lt;p&gt;Once a system has been able to establish this, we come to...&lt;/p&gt;

&lt;h3&gt;
  
  
  Authorization
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Authorization&lt;/strong&gt; deals with granting or denying rights to access resources. &lt;/p&gt;

&lt;h3&gt;
  
  
  Standards
&lt;/h3&gt;

&lt;p&gt;You may recall that I mentioned that auth is guided by clearly-defined standards. But where do these standards come from in the first place?&lt;/p&gt;

&lt;p&gt;There are many different standards and organizations that govern how things work on the internet. Two bodies that are of &lt;em&gt;particular interest to us in the context of authentication and authorization&lt;/em&gt; are the Internet Engineering Task Force (IETF) and the OpenID Foundation (OIDF).&lt;/p&gt;

&lt;h4&gt;
  
  
  IETF (Internet Engineering Task Force)
&lt;/h4&gt;

&lt;p&gt;The &lt;a href="https://ietf.org" rel="noopener noreferrer"&gt;IETF&lt;/a&gt; is a large, open, international community of network designers, operators, vendors, and researchers who are concerned with the evolution of internet architecture and the smooth operation of the internet.&lt;/p&gt;

&lt;p&gt;Really, that's a fancy way to say that &lt;strong&gt;dedicated professionals cooperate to write technical documents that guide us in how things should be done on the internet.&lt;/strong&gt;&lt;/p&gt;

&lt;h4&gt;
  
  
  OIDF (OpenID Foundation)
&lt;/h4&gt;

&lt;p&gt;The &lt;a href="https://openid.net/foundation/" rel="noopener noreferrer"&gt;OIDF&lt;/a&gt; is a non-profit, international  organization of people and companies who are committed to enabling, promoting, and protecting OpenID technologies.&lt;/p&gt;

&lt;p&gt;Now that we are aware of the specs and who writes them, let's circle back around to &lt;em&gt;authorization&lt;/em&gt; and talk about:&lt;/p&gt;

&lt;h1&gt;
  
  
  OAuth 2.0
&lt;/h1&gt;

&lt;p&gt;&lt;a href="https://tools.ietf.org/html/rfc6749" rel="noopener noreferrer"&gt;OAuth 2.0&lt;/a&gt; is one of the most frequently mentioned specs when it comes to the web — and also one that is &lt;em&gt;often mis-represented or misunderstood&lt;/em&gt;. How so?&lt;/p&gt;

&lt;p&gt;&lt;em&gt;OAuth is not an authentication spec.&lt;/em&gt; OAuth deals with &lt;em&gt;delegated authorization&lt;/em&gt;. Remember that authentication is about verifying the identity of a user. Authorization deals with granting or denying access to resources. OAuth 2.0 grants access to applications on the behalf of users. (Don't worry, we'll get to the authentication part in a little bit!)&lt;/p&gt;

&lt;h2&gt;
  
  
  Before OAuth
&lt;/h2&gt;

&lt;p&gt;To understand the purpose of OAuth, we need to do go back in time. OAuth 1.0 was established in December 2007. Before then, if we needed to &lt;strong&gt;access third party resources&lt;/strong&gt;, it looked like this:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fxcc4mwm3l6ix0h4hzc71.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fxcc4mwm3l6ix0h4hzc71.gif" alt="Before OAuth" width="480" height="270"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Let's say you used an app called HireMe123. HireMe123 wants to set up a calendar event (such as an interview appointment) on your (the user's) behalf. HireMe123 doesn't have its own calendar; it wants to use another service called MyCalApp to add events.&lt;/p&gt;

&lt;p&gt;Once you were logged into HireMe123, HireMe123 would &lt;em&gt;ask you for your MyCalApp login credentials&lt;/em&gt;. You would enter your MyCalApp username and password into HireMe123's site.&lt;/p&gt;

&lt;p&gt;HireMe123 then used your MyCalApp login to gain access to MyCalApp's API, and could then create calendar events using &lt;em&gt;your&lt;/em&gt; MyCalApp credentials.&lt;/p&gt;

&lt;h3&gt;
  
  
  Sharing Credentials is Bad!
&lt;/h3&gt;

&lt;p&gt;This approach relied on sharing a user's personal credentials from one app with a completely different app, and this is &lt;strong&gt;not good&lt;/strong&gt;. How so?&lt;/p&gt;

&lt;p&gt;For one thing, HireMe123 had &lt;em&gt;much less at stake&lt;/em&gt; in the protection of your MyCalApp login information. If HireMe123 didn't protect your MyCalApp credentials appropriately and they ended up stolen or breached, someone might write some nasty blog articles, but &lt;em&gt;HireMe123&lt;/em&gt; wouldn't face a catastrophe the way MyCalApp would.&lt;/p&gt;

&lt;p&gt;HireMe123 also had &lt;em&gt;way too much access&lt;/em&gt; to MyCalApp. HireMe123 had the same amount of access that you did, because they used your credentials to gain that access. That meant that HireMe123 could read all your calendar events, delete events, modify your calendar settings, etc.&lt;/p&gt;

&lt;h2&gt;
  
  
  Enter OAuth
&lt;/h2&gt;

&lt;p&gt;This leads us to OAuth.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;OAuth 2.0&lt;/strong&gt; is an open standard for performing delegated authorization. It's a specification that tells us how to grant third party access to APIs without exposing credentials. &lt;/p&gt;

&lt;p&gt;Using OAuth, the user can now &lt;em&gt;delegate&lt;/em&gt; HireMe123 to call MyCalApp on the user's behalf. MyCalApp can limit access to its API when called by third party clients without the risks of sharing login information or providing &lt;em&gt;too much&lt;/em&gt; access. It does this using an:&lt;/p&gt;

&lt;h2&gt;
  
  
  Authorization Server
&lt;/h2&gt;

&lt;p&gt;An &lt;strong&gt;authorization server&lt;/strong&gt; is a set of endpoints to interact with the user and issue tokens. How does this help?&lt;/p&gt;

&lt;p&gt;Let's revisit the situation with HireMe123 and MyCalApp, only now we have OAuth 2.0:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F7uoywh86pn5lta9dk30h.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F7uoywh86pn5lta9dk30h.gif" alt="Authorization with OAuth 2.0" width="480" height="270"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;MyCalApp now has an authorization server. Let's assume that HireMe123 has already registered as a known client with MyCalApp, which means that MyCalApp's authorization server recognizes HireMe123 as an entity that may ask for access to its API.&lt;/p&gt;

&lt;p&gt;Let's also assume you're already logged in with HireMe123 through whatever authentication HireMe123 has set up for itself. HireMe123 now wants to create events on your behalf.&lt;/p&gt;

&lt;p&gt;HireMe123 sends an &lt;em&gt;authorization request&lt;/em&gt; to MyCalApp's authorization server. In response, MyCalApp's authorization server prompts you — the user — to log in with MyCalApp (if you're not already logged in). You authenticate with MyCalApp.&lt;/p&gt;

&lt;p&gt;The MyCalApp authorization server then &lt;em&gt;prompts you for your consent&lt;/em&gt; to allow HireMe123 to access MyCalApp's APIs on your behalf. A prompt opens in the browser and specifically asks for your consent to let HireMe123 &lt;em&gt;add calendar events&lt;/em&gt; (but no more than that).&lt;/p&gt;

&lt;p&gt;If you say yes and grant your consent, then the MyCalApp authorization server will send an &lt;em&gt;authorization code&lt;/em&gt; to HireMe123. This lets HireMe123 know that the MyCalApp user (you) did indeed agree to allow HireMe123 to add events using the user's (your) MyCalApp.&lt;/p&gt;

&lt;p&gt;MyCalApp will then issue an &lt;em&gt;access token&lt;/em&gt; to HireMe123. HireMe123 can use that access token to call the MyCalApp API within the scope of permissions that were accepted by you and create events for you using the MyCalApp API.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Nothing insidious is happening now!&lt;/strong&gt; &lt;em&gt;MyCalApp is asking the user to log in with MyCalApp&lt;/em&gt;. HireMe123 is &lt;em&gt;not&lt;/em&gt; asking for the user's MyCalApp credentials. The issues with sharing credentials and too much access are no longer a problem.&lt;/p&gt;

&lt;h4&gt;
  
  
  What About Authentication?
&lt;/h4&gt;

&lt;p&gt;At this point, I hope it's been made clear that &lt;em&gt;OAuth is for delegated access&lt;/em&gt;. It doesn't cover &lt;em&gt;authentication&lt;/em&gt;. At any point where authentication was involved in the processes we covered above, login was managed by whatever login process HireMe123 or MyCalApp had implemented at their own discretion. OAuth 2.0 &lt;em&gt;didn't prescribe how&lt;/em&gt; this should be done: it only covered authorizing third party API access.&lt;/p&gt;

&lt;p&gt;So why are authentication and OAuth so often mentioned in the same breath?&lt;/p&gt;

&lt;h1&gt;
  
  
  The Login Problem
&lt;/h1&gt;

&lt;p&gt;The thing that happened after OAuth 2.0 established a way to access third party APIs was that &lt;em&gt;apps also wanted to log users in with other accounts&lt;/em&gt;. Using our example: let's say HireMe123 wanted a MyCalApp user to be able to &lt;em&gt;log into HireMe123 using their MyCalApp account&lt;/em&gt;, despite not having signed up for a HireMe123 account.&lt;/p&gt;

&lt;p&gt;But as we mentioned above, &lt;strong&gt;OAuth 2.0 is for delegated access&lt;/strong&gt;. It is &lt;em&gt;not&lt;/em&gt; an authentication protocol. That didn't stop people from trying to use it like one though, and this presented problems.&lt;/p&gt;

&lt;h2&gt;
  
  
  Problems with Using Access Tokens for Authentication
&lt;/h2&gt;

&lt;p&gt;If HireMe123 assumes successfully calling MyCalApp's API with an access token means the &lt;em&gt;user&lt;/em&gt; can be considered authenticated with HireMe123, we run into problems because we have no way to verify the access token was issued to a particular individual.&lt;/p&gt;

&lt;p&gt;For example:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Someone could have stolen the access token from a different user&lt;/li&gt;
&lt;li&gt;The access token could have been obtained from another client (not HireMe123) and injected into HireMe123&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This is called the &lt;strong&gt;confused deputy problem&lt;/strong&gt;. HireMe123 doesn't know &lt;em&gt;where&lt;/em&gt; this token came from or &lt;em&gt;who&lt;/em&gt; it was issued for. If we recall: &lt;strong&gt;authentication is about verifying the user is who they say they are&lt;/strong&gt;. HireMe123 can't know this from the fact that it can use this access token to access an API.&lt;/p&gt;

&lt;p&gt;As mentioned, this didn't stop people from misusing access tokens and OAuth 2.0 for authentication anyway. It quickly became evident that formalization of authentication &lt;em&gt;on top of OAuth 2.0&lt;/em&gt; was necessary to allow logins with third party applications while keeping apps and their users safe.&lt;/p&gt;

&lt;h1&gt;
  
  
  OpenID Connect
&lt;/h1&gt;

&lt;p&gt;This brings us to the specification called &lt;a href="https://openid.net/specs" rel="noopener noreferrer"&gt;OpenID Connect&lt;/a&gt;, or OIDC. OIDC is a spec &lt;em&gt;on top of OAuth 2.0&lt;/em&gt; that says how to authenticate users. The &lt;a href="https://openid.net/foundation/" rel="noopener noreferrer"&gt;OpenID Foundation (OIDF)&lt;/a&gt; is the steward of the OIDC standards.&lt;/p&gt;

&lt;p&gt;OIDC is an identity layer for authenticating users with an authorization server. Remember that an authorization server &lt;em&gt;issues tokens&lt;/em&gt;. &lt;strong&gt;Tokens&lt;/strong&gt; are encoded pieces of data for transmitting information between parties (such as an authorization server, application, or resource API). In the case of OIDC and authentication, the authorization server issues &lt;em&gt;ID tokens&lt;/em&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  ID Tokens
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;ID tokens&lt;/strong&gt; provide information about the authentication event and they identify the user. ID tokens are &lt;em&gt;intended for the client&lt;/em&gt;. They're a fixed format that the client can parse and validate to extract identity information from the token and thereby authenticate the user.&lt;/p&gt;

&lt;p&gt;OIDC declares a &lt;em&gt;fixed format&lt;/em&gt; for ID tokens, which is:&lt;/p&gt;

&lt;h3&gt;
  
  
  JSON Web Token (JWT)
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://tools.ietf.org/html/rfc7519" rel="noopener noreferrer"&gt;JSON Web Tokens&lt;/a&gt;, or &lt;a href="https://jwt.io" rel="noopener noreferrer"&gt;JWT&lt;/a&gt; (sometimes pronounced "jot"), are composed of three URL-safe string segments concatenated with periods &lt;code&gt;.&lt;/code&gt;&lt;/p&gt;

&lt;h4&gt;
  
  
  Header Segment
&lt;/h4&gt;

&lt;p&gt;The first segment is the &lt;strong&gt;header segment&lt;/strong&gt;. It might look something like this:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;The header segment is a JSON object containing a signing algorithm and token type. It is &lt;a href="https://tools.ietf.org/html/rfc4648#section-5" rel="noopener noreferrer"&gt;&lt;code&gt;base64Url&lt;/code&gt; encoded&lt;/a&gt; (byte data represented as text that is URL and filename safe).&lt;/p&gt;

&lt;p&gt;Decoded, it looks something like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"alg"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"RS256"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"typ"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"JWT"&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  Payload Segment
&lt;/h4&gt;

&lt;p&gt;The second segment is the &lt;strong&gt;payload segment&lt;/strong&gt;. It might look like this:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiYWRtaW4iOnRydWUsImlhdCI6MTUxNjIzOTAyMn0&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;This is a JSON object containing data &lt;em&gt;claims&lt;/em&gt;, which are statements about the user and the authentication event. For example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"sub"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"1234567890"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"John Doe"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"admin"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"iat"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;1516239022&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This is also &lt;code&gt;base64Url&lt;/code&gt; encoded.&lt;/p&gt;

&lt;h4&gt;
  
  
  Crypto Segment
&lt;/h4&gt;

&lt;p&gt;The final segment is the &lt;strong&gt;crypto segment&lt;/strong&gt;, or &lt;strong&gt;signature&lt;/strong&gt;. JWTs are signed so they can't be modified in transit. When an authorization server issues a token, it signs it using a key.&lt;/p&gt;

&lt;p&gt;When the client receives the ID token, the client &lt;strong&gt;validates the signature&lt;/strong&gt; using a key as well. (If an asymmetric signing algorithm was used, different keys are used to sign and validate; if this is case, only the authorization server holds the ability to sign tokens.)&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;Don't worry if this seems confusing. The details of how this works shouldn't trouble you or keep you from effectively using an authorization server with token-based authentication. If you're interested in demystifying the terms, jargon, and details behind JWT signing, check out my article on &lt;a href="https://dev.to/kimmaida/signing-and-validating-json-web-tokens-jwt-for-everyone-25fb"&gt;Signing and Validating JSON Web Tokens (JWT) for Everyone&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h3&gt;
  
  
  Claims
&lt;/h3&gt;

&lt;p&gt;Now that we know about the &lt;em&gt;anatomy&lt;/em&gt; of a JWT, let's talk more about the &lt;strong&gt;claims&lt;/strong&gt;, those statements from the Payload Segment. As per their moniker, ID tokens provide &lt;em&gt;identity&lt;/em&gt; information, which is present in the claims.&lt;/p&gt;

&lt;h4&gt;
  
  
  Authentication Claims
&lt;/h4&gt;

&lt;p&gt;We'll start with &lt;em&gt;&lt;a href="https://openid.net/specs/openid-connect-core-1_0.html#IDToken" rel="noopener noreferrer"&gt;statements about the authentication event&lt;/a&gt;&lt;/em&gt;. Here are a few examples of these claims:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"iss"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"https://{you}.authz-server.com"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"aud"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"RxHBtq2HL6biPljKRLNByqehlKhN1nCx"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"exp"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;1570019636365&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="err"&gt; &lt;/span&gt;&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="nl"&gt;"iat"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;1570016110289&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="err"&gt; &lt;/span&gt;&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="nl"&gt;"nonce"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"3yAjXLPq8EPP0S"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="err"&gt;...&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Some of the required authentication claims in an ID token include:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;iss&lt;/code&gt; &lt;em&gt;(issuer)&lt;/em&gt;: the issuer of the JWT, e.g., the authorization server&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;aud&lt;/code&gt; &lt;em&gt;(audience)&lt;/em&gt;: the intended recipient of the JWT; for ID tokens, this must be the client ID of the application receiving the token&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;exp&lt;/code&gt; &lt;em&gt;(expiration time)&lt;/em&gt;: expiration time; the ID token must not be accepted after this time&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;iat&lt;/code&gt; &lt;em&gt;(issued at time)&lt;/em&gt;: time at which the ID token was issued&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;A &lt;code&gt;nonce&lt;/code&gt; &lt;em&gt;binds the client's authorization request to the token it receives&lt;/em&gt;. The nonce is a &lt;a href="https://auth0.com/docs/api-auth/tutorials/nonce" rel="noopener noreferrer"&gt;cryptographically random string&lt;/a&gt; that the client creates and sends with an authorization request. The authorization server then places the nonce in the token that is sent back to the app. The app verifies that the nonce in the token matches the one sent with the authorization request. This way, the app can verify that the token came from the place it requested the token from in the first place.&lt;/p&gt;

&lt;h4&gt;
  
  
  Identity Claims
&lt;/h4&gt;

&lt;p&gt;Claims also include &lt;em&gt;&lt;a href="https://openid.net/specs/openid-connect-core-1_0.html#StandardClaims" rel="noopener noreferrer"&gt;statements about the end user&lt;/a&gt;&lt;/em&gt;.  Here are a few examples of these claims:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"sub"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"google-oauth2|102582972157289381734"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Kim Maida"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"picture"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"https://gravatar[...]"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"twitter"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"https://twitter.com/KimMaida"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"email"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"kim@gatsbyjs.com"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="err"&gt;...&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Some of the standard profile claims in an ID token include:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;sub&lt;/code&gt; &lt;em&gt;(subject)&lt;/em&gt;: unique identifier for the user; required&lt;/li&gt;
&lt;li&gt;&lt;code&gt;email&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;email_verified&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;birthdate&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;em&gt;etc.&lt;/em&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;We've now been through a crash-course on the important specifications (OAuth 2.0 and OpenID Connect) and it's time to see how to &lt;strong&gt;put our identity knowledge to work&lt;/strong&gt;.&lt;/p&gt;

&lt;h1&gt;
  
  
  Authentication with ID Tokens
&lt;/h1&gt;

&lt;p&gt;Let's see OIDC authentication in practice.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;Note that this is a simplified diagram. There are a few different flows depending on your application architecture.&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ftqure8mdp07rl8jr93ck.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ftqure8mdp07rl8jr93ck.gif" alt="authentication with ID tokens in the browser" width="480" height="270"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Our entities here are: the &lt;em&gt;browser&lt;/em&gt;, an &lt;em&gt;application&lt;/em&gt; running in the browser, and the &lt;em&gt;authorization server&lt;/em&gt;. When a user wants to log in, the app sends an authorization request to the authorization server. The user's credentials are verified by the authorization server, and if everything checks out, the authorization server issues an ID token to the application.&lt;/p&gt;

&lt;p&gt;The client application then decodes the ID token (which is a JWT) and verifies it. This includes validating the signature, and we must also verify the claims. Some examples of claim verification include:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;issuer (&lt;code&gt;iss&lt;/code&gt;): was this token issued by the expected authorization server?&lt;/li&gt;
&lt;li&gt;audience (&lt;code&gt;aud&lt;/code&gt;): is our app the target recipient of this token?&lt;/li&gt;
&lt;li&gt;expiration (&lt;code&gt;exp&lt;/code&gt;): is this token within a valid timeframe for use?&lt;/li&gt;
&lt;li&gt;nonce (&lt;code&gt;nonce&lt;/code&gt;): can we tie this token back to the authorization request our app made?&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Once we've established the authenticity of the ID token, the user is &lt;em&gt;authenticated&lt;/em&gt;. We also now have access to the identity claims and know &lt;em&gt;who&lt;/em&gt; this user is.&lt;/p&gt;

&lt;p&gt;Now the user is &lt;em&gt;authenticated&lt;/em&gt;. It's time to interact with an API.&lt;/p&gt;

&lt;h1&gt;
  
  
  Accessing APIs with Access Tokens
&lt;/h1&gt;

&lt;p&gt;We talked a bit about access tokens earlier, back when we were looking at how delegated access works with OAuth 2.0 and authorization servers. Let's look at some of the &lt;em&gt;details&lt;/em&gt; of how that works, going back to our scenario with HireMe123 and MyCalApp.&lt;/p&gt;

&lt;h2&gt;
  
  
  Access Tokens
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Access tokens&lt;/strong&gt; are used for &lt;em&gt;granting access to resources&lt;/em&gt;. With an access token issued by MyCalApp's authorization server, HireMe123 can access MyCalApp's API.&lt;/p&gt;

&lt;p&gt;Unlike ID tokens, which OIDC declares as JSON Web Tokens, &lt;strong&gt;access tokens have no specific, defined format&lt;/strong&gt;. They do not have to be (and aren't necessarily) JWT. However, many identity solutions use JWTs for access tokens because the format enables validation.&lt;/p&gt;

&lt;h3&gt;
  
  
  Access Tokens are Opaque to the Client
&lt;/h3&gt;

&lt;p&gt;Access tokens are for the &lt;em&gt;resource API&lt;/em&gt; and it is important that they are &lt;strong&gt;opaque to the client.&lt;/strong&gt; Why? &lt;/p&gt;

&lt;p&gt;Access tokens can change at any time. They should have short expiration times, so a user may frequently get new ones. They can also be re-issued to access different APIs or exercise different permissions. The &lt;em&gt;client&lt;/em&gt; application should never contain code that relies on the contents of the access token. Code that does so would be brittle, and is almost guaranteed to break.&lt;/p&gt;

&lt;h2&gt;
  
  
  Accessing Resource APIs
&lt;/h2&gt;

&lt;p&gt;Let's say we want to use an access token to call an API from a Single Page Application. What does this look like?&lt;/p&gt;

&lt;p&gt;We've covered authentication above, so let's assume the user is logged into our JS app in the browser. The app sends an authorization request to the authorization server, requesting an access token to call an API.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fy0nbp89ovuqa14ikg4gt.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fy0nbp89ovuqa14ikg4gt.gif" alt="Accessing an API with an access token" width="537" height="302"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Then when our app wants to interact with the API, we attach the access token to the request header, like so:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# HTTP request headers&lt;/span&gt;
Authorization: &lt;span class="s1"&gt;'Bearer eyj[...]'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The authorized request is then sent to the API, which verifies the token using middleware. If everything checks out, then the API returns data (e.g., JSON) to the application running in the browser.&lt;/p&gt;

&lt;p&gt;This is great, but there's something that may be occurring to you right about now. Earlier, we stated that OAuth solves problems with too much access. So how is that being addressed here?&lt;/p&gt;

&lt;h2&gt;
  
  
  Delegation with Scopes
&lt;/h2&gt;

&lt;p&gt;How does the API know what level of access it should give to the application that's requesting use of its API? We do this with &lt;strong&gt;scopes&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Scopes "&lt;a href="https://auth0.com/blog/on-the-nature-of-oauth2-scopes" rel="noopener noreferrer"&gt;limit what an application can do on the behalf of a user&lt;/a&gt;." They &lt;strong&gt;cannot grant privileges the user doesn't already have&lt;/strong&gt;. For example, if the MyCalApp user doesn't have permission to set up new MyCalApp enterprise accounts, scopes granted to &lt;em&gt;HireMe123&lt;/em&gt; won't ever allow the user to set up new enterprise accounts either.&lt;/p&gt;

&lt;p&gt;Scopes &lt;strong&gt;delegate access control&lt;/strong&gt; to the API or resource. The API is then responsible for &lt;em&gt;combining incoming scopes with actual user privileges&lt;/em&gt; to make the appropriate access control decisions.&lt;/p&gt;

&lt;p&gt;Let's walk through this with an example. &lt;/p&gt;

&lt;p&gt;I'm using the HireMe123 app and HireMe123 wants to access the third party MyCalApp API to create events on my behalf. HireMe123 has already requested an access token for MyCalApp from MyCalApp's authorization server. This token has some important information in it, such as:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;sub&lt;/code&gt;: (my MyCalApp user ID)&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;aud&lt;/code&gt;: &lt;code&gt;MyCalAppAPI&lt;/code&gt; (audience stating this token is intended for the MyCalApp API)&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;scope&lt;/code&gt;: &lt;code&gt;write:events&lt;/code&gt; (scope saying HireMe123 has permission to use the API to write events to my calendar)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;HireMe123 sends a request to the MyCalApp API with the access token in its authorization header. When the MyCalApp API receives this request, it can see that the token contains a &lt;code&gt;write:events&lt;/code&gt; scope.&lt;/p&gt;

&lt;p&gt;But MyCalApp hosts calendar accounts for &lt;em&gt;hundreds of thousands of users&lt;/em&gt;. In addition to looking at the &lt;code&gt;scope&lt;/code&gt; in the token, MyCalApp's API middleware needs to check the &lt;code&gt;sub&lt;/code&gt; subject identifier to make sure this request from HireMe123 is only able to exercise &lt;em&gt;my&lt;/em&gt; privileges to create events with &lt;em&gt;my&lt;/em&gt; MyCalApp account.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fi4i76ltyqgq3rfukmrn0.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fi4i76ltyqgq3rfukmrn0.gif" alt="delegated authorization with scopes and API access control" width="480" height="270"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;In the context of delegated authorization, scopes express what an application can do on the user's behalf. They're a subset of the user's total capabilities.&lt;/p&gt;

&lt;h3&gt;
  
  
  Granting Consent
&lt;/h3&gt;

&lt;p&gt;Remember when the authorization server asked the HireMe123 user for their consent to allow HireMe123 to use the user's privileges to access MyCalApp?&lt;/p&gt;

&lt;p&gt;That consent dialog might look something like this:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F22vtspdyqbyruyyxr0it.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F22vtspdyqbyruyyxr0it.gif" alt="consent dialog flow: HireMe123 is requesting access to your MyCalApp account to write:calendars" width="480" height="270"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;HireMe123 could ask for a variety of different scopes, for example:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;code&gt;write:events&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;read:events&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;read:settings&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;write:settings&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;...etc.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;In general, we should avoid overloading scopes with user-specific privileges. Scopes are for delegated permissions for an application. However, it &lt;em&gt;is&lt;/em&gt; possible to add different scopes to individual users if your authorization server provides &lt;a href="https://auth0.com/docs/authorization/concepts/rbac" rel="noopener noreferrer"&gt;Role-Based Access Control (RBAC)&lt;/a&gt;.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;With &lt;strong&gt;RBAC&lt;/strong&gt;, you can set up user roles with specific permissions in your authorization server. Then when the authorization server issues access tokens, it can include a specific user's roles in their scopes.&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h1&gt;
  
  
  Resources and What's Next?
&lt;/h1&gt;

&lt;p&gt;We covered a &lt;em&gt;lot&lt;/em&gt; of material, and it still wasn't anywhere close to everything. I do hope this was a helpful crash course in identity, authorization, and authentication. &lt;/p&gt;

&lt;p&gt;I'm currently working on a few additional blog posts that go into further depth on JSON Web Tokens and authentication and authorization for JavaScript applications.&lt;/p&gt;

&lt;p&gt;If you'd like to learn much, much more on these topics, here are some great resources for you to further your knowledge:&lt;/p&gt;

&lt;h2&gt;
  
  
  Learn More
&lt;/h2&gt;

&lt;p&gt;The &lt;strong&gt;&lt;a href="https://auth0.com/docs/videos/learn-identity" rel="noopener noreferrer"&gt;Learn Identity&lt;/a&gt; video series&lt;/strong&gt; in the &lt;a href="https://auth0.com/docs" rel="noopener noreferrer"&gt;Auth0 docs&lt;/a&gt; is the lecture portion of the new hire identity training for engineers at &lt;a href="https://auth0.com" rel="noopener noreferrer"&gt;Auth0&lt;/a&gt;, presented by Principal Architect &lt;a href="https://auth0.com/blog/auth0-welcomes-vittorio-bertocci/" rel="noopener noreferrer"&gt;Vittorio Bertocci&lt;/a&gt;. If you'd like to learn identity the way it’s done at Auth0, it's completely free and available to everyone (you don't even have to pay with a tweet or email!).&lt;/p&gt;

&lt;p&gt;The &lt;strong&gt;OAuth 2.0 and OpenID Connect specifications&lt;/strong&gt; are dense, but once you're familiar with the terminology and have foundational identity knowledge, they're helpful, informative, and become much more digestible. Check them out here: &lt;a href="https://tools.ietf.org/html/rfc6749" rel="noopener noreferrer"&gt;The OAuth 2.0 Authorization Framework&lt;/a&gt; and &lt;a href="https://openid.net/developers/specs/" rel="noopener noreferrer"&gt;OpenID Connect Specifications&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;a href="https://jwt.io" rel="noopener noreferrer"&gt;JWT.io&lt;/a&gt;&lt;/strong&gt; is a JSON Web Token resource that provides a debugger tool and directory of JWT signing/verification libraries for various technologies.&lt;/p&gt;

&lt;p&gt;The &lt;strong&gt;&lt;a href="https://openidconnect.net/" rel="noopener noreferrer"&gt;OpenID Connect Playground&lt;/a&gt;&lt;/strong&gt; is a debugger that lets developers explore and test OIDC calls and responses step-by-step.&lt;/p&gt;

&lt;h2&gt;
  
  
  Thank You!
&lt;/h2&gt;

&lt;p&gt;If you'd like to chat, I'm available on Twitter at &lt;a href="https://twitter.com/KimMaida" rel="noopener noreferrer"&gt;@KimMaida&lt;/a&gt;, and I also speak at &lt;a href="https://github.com/kmaida/about#events" rel="noopener noreferrer"&gt;conferences and events&lt;/a&gt;. I hope to see you sometime, and &lt;strong&gt;thank you so much for reading&lt;/strong&gt;!&lt;/p&gt;

</description>
      <category>authentication</category>
      <category>authorization</category>
      <category>oidc</category>
      <category>oauth2</category>
    </item>
  </channel>
</rss>
