{"componentChunkName":"component---src-pages-markdown-remark-fields-slug-js","path":"/engineering/pkce/","result":{"data":{"markdownRemark":{"id":"0867dd59-ba31-51af-b5ab-f5c10842430c","excerpt":"PKCE is an OAuth 2.0 security extension for public clients on mobile devices intended to avoid a malicious programme creeping into the same computer from…","html":"<p>PKCE is an OAuth 2.0 security extension for public clients on mobile devices intended to avoid a malicious programme creeping into the same computer from intercepting the authorisation code. The <a href=\"https://oauth.net/2/pkce/\">RFC 7636</a> introduction discusses the mechanisms of such an attack.</p>\n<p>PKCE has a different specification of its own. It allows applications to use the most reliable OAuth 2.0 flows in public or untrusted clients - the Authorization Code flow. In order to efficiently use a dynamically generated password, it achieves this by doing some setup work before the flow and some verification at the end of the flow. </p>\n<p>This is important because getting a fixed secret in a public client is not safe.</p>\n<p>In this blog, we will see how PKCE is useful in authorization code flow for OAuth and OIDC and how you can use this with your OAuth and OpenID Connect providers.</p>\n<h2 id=\"what-is-pkce\" style=\"position:relative;\"><a href=\"#what-is-pkce\" aria-label=\"what is pkce permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>What is PKCE</h2>\n<p>Proof Key for Code Exchange as known as PKCE, is a key for preventing malicious attacks and securely performing code authorization flow.</p>\n<p>I would say, PKCE is used to provide one more security layer to the authorization code flow in <a href=\"/oauth2/\">OAuth</a> and OpenID Connect.</p>\n<p>PKCE is mainly useful for the client-side application or any web apps that are using the client secret key and used to replace the static secret used in the authorization flow.</p>\n<p>This flow basically works with two parameters <strong>Code Verifier</strong> and <strong>Code challenge</strong>. Let's see what are these parameters, how we use them, and generate them.</p>\n<h3 id=\"pkce-code-verifier-and-challenge\" style=\"position:relative;\"><a href=\"#pkce-code-verifier-and-challenge\" aria-label=\"pkce code verifier and challenge permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>PKCE code verifier and challenge</h3>\n<p><strong>The code verifier</strong> is a cryptographically random string using the characters A-Z, a-z, 0-9, and the punctuation characters -._~ (hyphen, period, underscore, and tilde), between 43 and 128 characters long.\nOnce the client has generated the code verifier, it uses that to create the <strong>code challenge</strong>.</p>\n<p>For devices that can perform a SHA256 hash, the code challenge is a BASE64-URL-encoded string of the SHA256 hash of the code verifier.</p>\n<h3 id=\"generate-code-verifier-and-code-challenge\" style=\"position:relative;\"><a href=\"#generate-code-verifier-and-code-challenge\" aria-label=\"generate code verifier and code challenge permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Generate code verifier and code challenge</h3>\n<p>Here you can see the examples to generate the Code verifier and code challenge in different languages. Either you <a href=\"/oAuth-implemenation-using-node/\">can find Node</a> and <a href=\"/golang-maps/\">Go Packages</a> for this but I would recommend you to not depend on any package for such small things.</p>\n<p><strong>NodeJs</strong></p>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"javascript\" data-index=\"0\"><code class=\"grvsc-code\"><span class=\"grvsc-line\"><span class=\"mtk4\">var</span><span class=\"mtk1\"> </span><span class=\"mtk12\">crypto</span><span class=\"mtk1\"> = </span><span class=\"mtk11\">require</span><span class=\"mtk1\">(</span><span class=\"mtk8\">&quot;crypto&quot;</span><span class=\"mtk1\">)</span></span>\n<span class=\"grvsc-line\"></span>\n<span class=\"grvsc-line\"><span class=\"mtk4\">function</span><span class=\"mtk1\"> </span><span class=\"mtk11\">base64URLEncode</span><span class=\"mtk1\">(</span><span class=\"mtk12\">str</span><span class=\"mtk1\">) {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk15\">return</span><span class=\"mtk1\"> </span><span class=\"mtk12\">str</span><span class=\"mtk1\">.</span><span class=\"mtk11\">toString</span><span class=\"mtk1\">(</span><span class=\"mtk8\">&#39;base64&#39;</span><span class=\"mtk1\">)</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        .</span><span class=\"mtk11\">replace</span><span class=\"mtk1\">(</span><span class=\"mtk5\">/</span><span class=\"mtk6\">\\+</span><span class=\"mtk5\">/</span><span class=\"mtk4\">g</span><span class=\"mtk1\">, </span><span class=\"mtk8\">&#39;-&#39;</span><span class=\"mtk1\">)</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        .</span><span class=\"mtk11\">replace</span><span class=\"mtk1\">(</span><span class=\"mtk5\">/</span><span class=\"mtk6\">\\/</span><span class=\"mtk5\">/</span><span class=\"mtk4\">g</span><span class=\"mtk1\">, </span><span class=\"mtk8\">&#39;_&#39;</span><span class=\"mtk1\">)</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        .</span><span class=\"mtk11\">replace</span><span class=\"mtk1\">(</span><span class=\"mtk5\">/=/</span><span class=\"mtk4\">g</span><span class=\"mtk1\">, </span><span class=\"mtk8\">&#39;&#39;</span><span class=\"mtk1\">);</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">}</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk4\">var</span><span class=\"mtk1\"> </span><span class=\"mtk12\">verifier</span><span class=\"mtk1\"> = </span><span class=\"mtk11\">base64URLEncode</span><span class=\"mtk1\">(</span><span class=\"mtk12\">crypto</span><span class=\"mtk1\">.</span><span class=\"mtk11\">randomBytes</span><span class=\"mtk1\">(</span><span class=\"mtk7\">32</span><span class=\"mtk1\">));</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk10\">console</span><span class=\"mtk1\">.</span><span class=\"mtk11\">log</span><span class=\"mtk1\">(</span><span class=\"mtk8\">&quot;code_verifier: &quot;</span><span class=\"mtk1\">, </span><span class=\"mtk12\">verifier</span><span class=\"mtk1\">)</span></span>\n<span class=\"grvsc-line\"></span>\n<span class=\"grvsc-line\"><span class=\"mtk15\">if</span><span class=\"mtk1\">(</span><span class=\"mtk12\">verifier</span><span class=\"mtk1\">){</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk4\">var</span><span class=\"mtk1\"> </span><span class=\"mtk12\">challenge</span><span class=\"mtk1\"> = </span><span class=\"mtk11\">base64URLEncode</span><span class=\"mtk1\">(</span><span class=\"mtk11\">sha256</span><span class=\"mtk1\">(</span><span class=\"mtk12\">verifier</span><span class=\"mtk1\">));</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk10\">console</span><span class=\"mtk1\">.</span><span class=\"mtk11\">log</span><span class=\"mtk1\">(</span><span class=\"mtk8\">&quot;code_challenge: &quot;</span><span class=\"mtk1\">,</span><span class=\"mtk12\">challenge</span><span class=\"mtk1\">)</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">}</span></span>\n<span class=\"grvsc-line\"></span>\n<span class=\"grvsc-line\"></span>\n<span class=\"grvsc-line\"><span class=\"mtk4\">function</span><span class=\"mtk1\"> </span><span class=\"mtk11\">sha256</span><span class=\"mtk1\">(</span><span class=\"mtk12\">buffer</span><span class=\"mtk1\">) {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk15\">return</span><span class=\"mtk1\"> </span><span class=\"mtk12\">crypto</span><span class=\"mtk1\">.</span><span class=\"mtk11\">createHash</span><span class=\"mtk1\">(</span><span class=\"mtk8\">&#39;sha256&#39;</span><span class=\"mtk1\">).</span><span class=\"mtk11\">update</span><span class=\"mtk1\">(</span><span class=\"mtk12\">buffer</span><span class=\"mtk1\">).</span><span class=\"mtk11\">digest</span><span class=\"mtk1\">();</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">}</span></span></code></pre>\n<p><strong>Golang</strong></p>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"golang\" data-index=\"1\"><code class=\"grvsc-code\"><span class=\"grvsc-line\">package main</span>\n<span class=\"grvsc-line\"> </span>\n<span class=\"grvsc-line\">import (</span>\n<span class=\"grvsc-line\">    &quot;crypto/sha256&quot;</span>\n<span class=\"grvsc-line\">    &quot;encoding/base64&quot;</span>\n<span class=\"grvsc-line\">    &quot;fmt&quot;</span>\n<span class=\"grvsc-line\">    &quot;math/rand&quot;</span>\n<span class=\"grvsc-line\">    &quot;strings&quot;</span>\n<span class=\"grvsc-line\">    &quot;time&quot;</span>\n<span class=\"grvsc-line\">)</span>\n<span class=\"grvsc-line\"> </span>\n<span class=\"grvsc-line\">type CodeVerifier struct {</span>\n<span class=\"grvsc-line\">    Value string</span>\n<span class=\"grvsc-line\">}</span>\n<span class=\"grvsc-line\"> </span>\n<span class=\"grvsc-line\">const (</span>\n<span class=\"grvsc-line\">    length = 32</span>\n<span class=\"grvsc-line\">)</span>\n<span class=\"grvsc-line\"> </span>\n<span class=\"grvsc-line\">func base64URLEncode(str []byte) string {</span>\n<span class=\"grvsc-line\">    encoded := base64.StdEncoding.EncodeToString(str)</span>\n<span class=\"grvsc-line\">    encoded = strings.Replace(encoded, &quot;+&quot;, &quot;-&quot;, -1)</span>\n<span class=\"grvsc-line\">    encoded = strings.Replace(encoded, &quot;/&quot;, &quot;_&quot;, -1)</span>\n<span class=\"grvsc-line\">    encoded = strings.Replace(encoded, &quot;=&quot;, &quot;&quot;, -1)</span>\n<span class=\"grvsc-line\">    return encoded</span>\n<span class=\"grvsc-line\">}</span>\n<span class=\"grvsc-line\"> </span>\n<span class=\"grvsc-line\">func verifier() (*CodeVerifier, error) {</span>\n<span class=\"grvsc-line\">    r := rand.New(rand.NewSource(time.Now().UnixNano()))</span>\n<span class=\"grvsc-line\">    b := make([]byte, length, length)</span>\n<span class=\"grvsc-line\">    for i := 0; i &lt; length; i++ {</span>\n<span class=\"grvsc-line\">        b[i] = byte(r.Intn(255))</span>\n<span class=\"grvsc-line\">    }</span>\n<span class=\"grvsc-line\">    return CreateCodeVerifierFromBytes(b)</span>\n<span class=\"grvsc-line\">}</span>\n<span class=\"grvsc-line\"> </span>\n<span class=\"grvsc-line\">func CreateCodeVerifierFromBytes(b []byte) (*CodeVerifier, error) {</span>\n<span class=\"grvsc-line\">    return &CodeVerifier{</span>\n<span class=\"grvsc-line\">        Value: base64URLEncode(b),</span>\n<span class=\"grvsc-line\">    }, nil</span>\n<span class=\"grvsc-line\">}</span>\n<span class=\"grvsc-line\"> </span>\n<span class=\"grvsc-line\">func (v *CodeVerifier) CodeChallengeS256() string {</span>\n<span class=\"grvsc-line\">    h := sha256.New()</span>\n<span class=\"grvsc-line\">    h.Write([]byte(v.Value))</span>\n<span class=\"grvsc-line\">    return base64URLEncode(h.Sum(nil))</span>\n<span class=\"grvsc-line\">}</span>\n<span class=\"grvsc-line\"> </span>\n<span class=\"grvsc-line\">func main() {</span>\n<span class=\"grvsc-line\">    verifier, _ := verifier()</span>\n<span class=\"grvsc-line\">    fmt.Println(&quot;code_verifier: &quot;, verifier.Value)</span>\n<span class=\"grvsc-line\">    challenge := verifier.CodeChallengeS256()</span>\n<span class=\"grvsc-line\">    fmt.Println(&quot;code_challenge :&quot;, challenge)</span>\n<span class=\"grvsc-line\">}</span>\n<span class=\"grvsc-line\"> </span></code></pre>\n<h2 id=\"implement-the-oauth-20-authorization-code-with-pkce-flow\" style=\"position:relative;\"><a href=\"#implement-the-oauth-20-authorization-code-with-pkce-flow\" aria-label=\"implement the oauth 20 authorization code with pkce flow permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Implement the OAuth 2.0 Authorization Code with PKCE Flow</h2>\n<h3 id=\"get-the-authorization-code\" style=\"position:relative;\"><a href=\"#get-the-authorization-code\" aria-label=\"get the authorization code permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Get the Authorization code</h3>\n<p>In the OAuth Authorization flow, we need to have the code verifier and code challenge to start with the authentication and obviously an OAuth provider to connect.</p>\n<p> For the initial request, we need to pass the code<em>challenge and code</em>challenge_method to the OAuth or OIDC provider that supports PKCE based flow.</p>\n<p>The request will look like: </p>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"\" data-index=\"2\"><code class=\"grvsc-code\"><span class=\"grvsc-line\">Provider + /oauth/redirect?</span>\n<span class=\"grvsc-line\">client_id={client_id}</span>\n<span class=\"grvsc-line\">&redirect_uri={Callback URL}</span>\n<span class=\"grvsc-line\">&scope={Scope}</span>\n<span class=\"grvsc-line\">&response_type=code</span>\n<span class=\"grvsc-line\">&state={random long string}</span>\n<span class=\"grvsc-line\">&code_challenge={code challenge}</span>\n<span class=\"grvsc-line\">&code_challenge_method=SHA256</span></code></pre>\n<p>The provider should redirect you to the authentication/login page and where you’ll get the code after successful authentication.</p>\n<h3 id=\"code-exchange\" style=\"position:relative;\"><a href=\"#code-exchange\" aria-label=\"code exchange permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Code Exchange</h3>\n<p>In the code exchange request, we need to pass the code we have received through the above request and the code verifier that we have generated in our first step.</p>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"\" data-index=\"3\"><code class=\"grvsc-code\"><span class=\"grvsc-line\">POST Provider + /oauth/access_token</span>\n<span class=\"grvsc-line\"></span>\n<span class=\"grvsc-line\">Request body:</span>\n<span class=\"grvsc-line\">{</span>\n<span class=\"grvsc-line\">   client_id:{client_id},</span>\n<span class=\"grvsc-line\">   client_secret:{client_secret},</span>\n<span class=\"grvsc-line\">   redirect_uri:{redirect_uri},</span>\n<span class=\"grvsc-line\">   response_type:token,</span>\n<span class=\"grvsc-line\">   Code:{code} // That we have received in authorization request</span>\n<span class=\"grvsc-line\">   code_verifier: {code verifier // generated in the first step</span>\n<span class=\"grvsc-line\">}</span></code></pre>\n<p>Once the code<em>verificer hash matches with the code</em>challenge of the authorization request, You will get the token in the response with status code 200 OK.</p>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"\" data-index=\"4\"><code class=\"grvsc-code\"><span class=\"grvsc-line\">{</span>\n<span class=\"grvsc-line\">    &quot;access_token&quot;: &quot;c5a****b-****-4*7f-a********e4a&quot;,</span>\n<span class=\"grvsc-line\">    &quot;token_type&quot;: &quot;access_token&quot;,</span>\n<span class=\"grvsc-line\">    &quot;refresh_token&quot;: &quot;5*****82-b***-**82-8c*1-*******7ce&quot;,</span>\n<span class=\"grvsc-line\">    &quot;expires_in&quot;: 11972</span>\n<span class=\"grvsc-line\">}</span></code></pre>\n<p>That's it and you've implemented PKCE flow in your application.</p>\n<style class=\"grvsc-styles\">\n  .grvsc-container {\n    overflow: auto;\n    -webkit-overflow-scrolling: touch;\n    padding-top: 1rem;\n    padding-top: var(--grvsc-padding-top, var(--grvsc-padding-v, 1rem));\n    padding-bottom: 1rem;\n    padding-bottom: var(--grvsc-padding-bottom, var(--grvsc-padding-v, 1rem));\n    border-radius: 8px;\n    border-radius: var(--grvsc-border-radius, 8px);\n    font-feature-settings: normal;\n  }\n  \n  .grvsc-code {\n    display: inline-block;\n    min-width: 100%;\n  }\n  \n  .grvsc-line {\n    display: inline-block;\n    box-sizing: border-box;\n    width: 100%;\n    padding-left: 1.5rem;\n    padding-left: var(--grvsc-padding-left, var(--grvsc-padding-h, 1.5rem));\n    padding-right: 1.5rem;\n    padding-right: var(--grvsc-padding-right, var(--grvsc-padding-h, 1.5rem));\n  }\n  \n  .grvsc-line-highlighted {\n    background-color: var(--grvsc-line-highlighted-background-color, transparent);\n    box-shadow: inset var(--grvsc-line-highlighted-border-width, 4px) 0 0 0 var(--grvsc-line-highlighted-border-color, transparent);\n  }\n  \n  .dark-default-dark {\n    background-color: #1E1E1E;\n    color: #D4D4D4;\n  }\n  .dark-default-dark .mtk4 { color: #569CD6; }\n  .dark-default-dark .mtk1 { color: #D4D4D4; }\n  .dark-default-dark .mtk12 { color: #9CDCFE; }\n  .dark-default-dark .mtk11 { color: #DCDCAA; }\n  .dark-default-dark .mtk8 { color: #CE9178; }\n  .dark-default-dark .mtk15 { color: #C586C0; }\n  .dark-default-dark .mtk5 { color: #D16969; }\n  .dark-default-dark .mtk6 { color: #D7BA7D; }\n  .dark-default-dark .mtk7 { color: #B5CEA8; }\n  .dark-default-dark .mtk10 { color: #4EC9B0; }\n</style>","headings":[{"value":"What is PKCE","depth":2},{"value":"PKCE code verifier and challenge","depth":3},{"value":"Generate code verifier and code challenge","depth":3},{"value":"Implement the OAuth 2.0 Authorization Code with PKCE Flow","depth":2},{"value":"Get the Authorization code","depth":3},{"value":"Code Exchange","depth":3}],"fields":{"slug":"/engineering/pkce/"},"frontmatter":{"metatitle":null,"metadescription":null,"description":"If you are working with OAuth and OIDC authorization code flow and want to setup PKCE flow then this article will help you to understand everything about PKCE.","title":"PKCE: What it is and how to use it with OAuth 2.0","canonical":null,"date":"September 03, 2020","updated_date":null,"tags":["PKCE","Oauth","OIDC"],"coverImage":{"childImageSharp":{"fluid":{"aspectRatio":1.5037593984962405,"src":"/static/7ba5011bcf44e895dd050e8766d4d005/c2ae5/pkce.png","srcSet":"/static/7ba5011bcf44e895dd050e8766d4d005/f5f11/pkce.png 200w,\n/static/7ba5011bcf44e895dd050e8766d4d005/6d133/pkce.png 400w,\n/static/7ba5011bcf44e895dd050e8766d4d005/c2ae5/pkce.png 600w","sizes":"(max-width: 600px) 100vw, 600px"}}},"author":{"id":"Narendra Pareek","github":"pareek-narendra","bio":"Narendra is a Product Manager at LoginRadius, where he is utilizing his skills in driving vision and roadmap for businesses. He focuses on collaboration between customer and company. He is also having a 5 years of develoment experience in different NodeJS, GO and PHP language projects.","avatar":null}}}},"pageContext":{"id":"0867dd59-ba31-51af-b5ab-f5c10842430c","fields__slug":"/engineering/pkce/","__params":{"fields__slug":"engineering"}}},"staticQueryHashes":["1171199041","1384082988","1711371485","1753898100","2100481360","229320306","23180105","528864852"]}