mirror of
https://github.com/ysoftdevs/oauth-playground-client.git
synced 2026-04-19 23:21:26 +02:00
Make state optional and do not use it by default in code, pkce and webauthn flows
This commit is contained in:
@@ -44,7 +44,7 @@
|
|||||||
Build the authorization URL and redirect the user to the authorization server
|
Build the authorization URL and redirect the user to the authorization server
|
||||||
</div>
|
</div>
|
||||||
<div class="col s4 circle-text">
|
<div class="col s4 circle-text">
|
||||||
After the user is redirected back to the client, verify that the state matches
|
The user is redirected back to the client
|
||||||
</div>
|
</div>
|
||||||
<div class="col s4 circle-text">
|
<div class="col s4 circle-text">
|
||||||
Exchange the authorization code for an access token
|
Exchange the authorization code for an access token
|
||||||
@@ -56,7 +56,7 @@
|
|||||||
<div class="card horizontal">
|
<div class="card horizontal">
|
||||||
<div class="card-stacked">
|
<div class="card-stacked">
|
||||||
<div class="card-content">
|
<div class="card-content">
|
||||||
<h6>2. Verify the state parameter</h6>
|
<h6>2. Parse response</h6>
|
||||||
<p>
|
<p>
|
||||||
You have now been redirected back to the application, to the page that was specified in the <b>redirect-url</b> parameter.
|
You have now been redirected back to the application, to the page that was specified in the <b>redirect-url</b> parameter.
|
||||||
In the URL you can notice, that there are addtional query parameters:
|
In the URL you can notice, that there are addtional query parameters:
|
||||||
@@ -64,7 +64,7 @@
|
|||||||
<pre class="code-block"><code id="queryParams"></code></pre>
|
<pre class="code-block"><code id="queryParams"></code></pre>
|
||||||
<p>Let's break it down...</p>
|
<p>Let's break it down...</p>
|
||||||
<ul class="collection">
|
<ul class="collection">
|
||||||
<li class="collection-item">
|
<li class="collection-item has-state">
|
||||||
<p><b><span class="emphasis">state</span>=<span id="state"></span></b></p>
|
<p><b><span class="emphasis">state</span>=<span id="state"></span></b></p>
|
||||||
<p>
|
<p>
|
||||||
The state parameter is an opaque value used by the client to maintain state between the request and the callback.
|
The state parameter is an opaque value used by the client to maintain state between the request and the callback.
|
||||||
@@ -81,10 +81,10 @@
|
|||||||
</p>
|
</p>
|
||||||
</li>
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
<p>
|
<p class="has-state">
|
||||||
Now we have everything necessary to obtain token for the user. But is the state we have sent (<b><span id="sent-state"></span></b>) equivalent to the one we received back (<b><span id="received-state"></span></b>)?
|
Now we have everything necessary to obtain token for the user. But is the state we have sent (<b><span id="sent-state"></span></b>) equivalent to the one we received back (<b><span id="received-state"></span></b>)?
|
||||||
</p>
|
</p>
|
||||||
<div class="row flow-submit-container">
|
<div class="row flow-submit-container has-state">
|
||||||
<div class="col m6 s12" style="margin-bottom: 5px;">
|
<div class="col m6 s12" style="margin-bottom: 5px;">
|
||||||
<a class="waves-effect waves-light btn btn-success full-width" onclick="proceedToNextStep()">States are matching</a>
|
<a class="waves-effect waves-light btn btn-success full-width" onclick="proceedToNextStep()">States are matching</a>
|
||||||
</div>
|
</div>
|
||||||
@@ -92,6 +92,10 @@
|
|||||||
<a class="waves-effect waves-light btn btn-error full-width" href="/flow/code">States are not matching</a>
|
<a class="waves-effect waves-light btn btn-error full-width" href="/flow/code">States are not matching</a>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<div class="row flow-submit-container no-state">
|
||||||
|
<a id="get-token-btn" class="waves-effect waves-light btn full-width" onClick="proceedToNextStep()">Continue</a>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -111,9 +115,9 @@
|
|||||||
const state = urlParams.get("state");
|
const state = urlParams.get("state");
|
||||||
const sentState = getCookie("state");
|
const sentState = getCookie("state");
|
||||||
|
|
||||||
if (!code || !state || !sentState) {
|
// if (!code || !state || !sentState) {
|
||||||
window.location = "/flow/expired";
|
// window.location = "/flow/expired";
|
||||||
}
|
// }
|
||||||
|
|
||||||
$("#queryParams").text(window.location.search)
|
$("#queryParams").text(window.location.search)
|
||||||
$("#state").text(state);
|
$("#state").text(state);
|
||||||
@@ -121,6 +125,9 @@
|
|||||||
$("#received-state").text(state);
|
$("#received-state").text(state);
|
||||||
$("#code").text(code);
|
$("#code").text(code);
|
||||||
|
|
||||||
|
$(".has-state").toggle(!!state);
|
||||||
|
$(".no-state").toggle(!state);
|
||||||
|
|
||||||
function proceedToNextStep() {
|
function proceedToNextStep() {
|
||||||
window.location.href = "/flow/code-3" + window.location.search;
|
window.location.href = "/flow/code-3" + window.location.search;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -44,7 +44,7 @@
|
|||||||
Build the authorization URL and redirect the user to the authorization server
|
Build the authorization URL and redirect the user to the authorization server
|
||||||
</div>
|
</div>
|
||||||
<div class="col s4 circle-text">
|
<div class="col s4 circle-text">
|
||||||
After the user is redirected back to the client, verify that the state matches
|
The user is redirected back to the client
|
||||||
</div>
|
</div>
|
||||||
<div class="col s4 circle-text">
|
<div class="col s4 circle-text">
|
||||||
Exchange the authorization code for an access token
|
Exchange the authorization code for an access token
|
||||||
|
|||||||
@@ -44,7 +44,7 @@
|
|||||||
Build the authorization URL and redirect the user to the authorization server
|
Build the authorization URL and redirect the user to the authorization server
|
||||||
</div>
|
</div>
|
||||||
<div class="col s4 circle-text">
|
<div class="col s4 circle-text">
|
||||||
After the user is redirected back to the client, verify that the state matches
|
The user is redirected back to the client
|
||||||
</div>
|
</div>
|
||||||
<div class="col s4 circle-text">
|
<div class="col s4 circle-text">
|
||||||
Exchange the authorization code for an access token
|
Exchange the authorization code for an access token
|
||||||
@@ -100,7 +100,7 @@
|
|||||||
token. In this case, we are requesting access to <b>photos</b> and <b>files</b>.
|
token. In this case, we are requesting access to <b>photos</b> and <b>files</b>.
|
||||||
</p>
|
</p>
|
||||||
</li>
|
</li>
|
||||||
<li class="collection-item">
|
<!-- <li class="collection-item">
|
||||||
<p><b><span class="emphasis">state</span>=<span id="state"></span></b></p>
|
<p><b><span class="emphasis">state</span>=<span id="state"></span></b></p>
|
||||||
<p>
|
<p>
|
||||||
State parameter. This is an <b>optional parameter</b> that the client can use to maintain
|
State parameter. This is an <b>optional parameter</b> that the client can use to maintain
|
||||||
@@ -108,7 +108,7 @@
|
|||||||
redirecting the user back to the client, allowing the client to verify that the response is coming from the
|
redirecting the user back to the client, allowing the client to verify that the response is coming from the
|
||||||
server and not a malicious third party (<a href="https://owasp.org/www-community/attacks/csrf" target="_blank">CSRF attack</a>).
|
server and not a malicious third party (<a href="https://owasp.org/www-community/attacks/csrf" target="_blank">CSRF attack</a>).
|
||||||
</p>
|
</p>
|
||||||
</li>
|
</li> -->
|
||||||
</ul>
|
</ul>
|
||||||
<p>
|
<p>
|
||||||
All that we now need to do is click the button below and login with our credentials.
|
All that we now need to do is click the button below and login with our credentials.
|
||||||
@@ -144,7 +144,8 @@
|
|||||||
+ "&" + "client_id=" + getClientId()
|
+ "&" + "client_id=" + getClientId()
|
||||||
+ "&" + "redirect_uri=" + redirectUri
|
+ "&" + "redirect_uri=" + redirectUri
|
||||||
+ "&" + "scope=" + scope
|
+ "&" + "scope=" + scope
|
||||||
+ "&" + "state=" + state;
|
//+ "&" + "state=" + state
|
||||||
|
;
|
||||||
}
|
}
|
||||||
|
|
||||||
function fillExample() {
|
function fillExample() {
|
||||||
@@ -153,7 +154,8 @@
|
|||||||
+ "&client_id=" + getClientId() + "\n"
|
+ "&client_id=" + getClientId() + "\n"
|
||||||
+ "&redirect_uri=" + redirectUri + "\n"
|
+ "&redirect_uri=" + redirectUri + "\n"
|
||||||
+ "&scope=" + scope + "\n"
|
+ "&scope=" + scope + "\n"
|
||||||
+ "&state=" + state;
|
//+ "&state=" + state
|
||||||
|
;
|
||||||
|
|
||||||
$("#requestUriExample").text(requestExample);
|
$("#requestUriExample").text(requestExample);
|
||||||
$("#baseUrl").text(baseUrl);
|
$("#baseUrl").text(baseUrl);
|
||||||
@@ -172,7 +174,7 @@
|
|||||||
|
|
||||||
const responseType = "code";
|
const responseType = "code";
|
||||||
const redirectUri = getRedirectUri();
|
const redirectUri = getRedirectUri();
|
||||||
const scope = "photos%20files";
|
const scope = "photos files";
|
||||||
const state = generateSessionState();
|
const state = generateSessionState();
|
||||||
setCookie("state", state, 5);
|
setCookie("state", state, 5);
|
||||||
|
|
||||||
|
|||||||
@@ -49,7 +49,7 @@
|
|||||||
Build the authorization URL and redirect the user to the authorization server
|
Build the authorization URL and redirect the user to the authorization server
|
||||||
</div>
|
</div>
|
||||||
<div class="col s3 circle-text">
|
<div class="col s3 circle-text">
|
||||||
After the user is redirected back to the client, verify the state
|
The user is redirected back to the client
|
||||||
</div>
|
</div>
|
||||||
<div class="col s3 circle-text">
|
<div class="col s3 circle-text">
|
||||||
Exchange the authorization code and code verifier for an access token
|
Exchange the authorization code and code verifier for an access token
|
||||||
@@ -103,7 +103,7 @@
|
|||||||
token. In this case, we are requesting access to <b>photos</b> and <b>files</b>.
|
token. In this case, we are requesting access to <b>photos</b> and <b>files</b>.
|
||||||
</p>
|
</p>
|
||||||
</li>
|
</li>
|
||||||
<li class="collection-item">
|
<!-- <li class="collection-item">
|
||||||
<p><b><span class="emphasis">state</span>=<span id="state"></span></b></p>
|
<p><b><span class="emphasis">state</span>=<span id="state"></span></b></p>
|
||||||
<p>
|
<p>
|
||||||
State parameter. This is an <b>optional parameter</b> that the client can use to maintain
|
State parameter. This is an <b>optional parameter</b> that the client can use to maintain
|
||||||
@@ -111,7 +111,7 @@
|
|||||||
user back to the client, allowing the client to verify that the response is coming from the
|
user back to the client, allowing the client to verify that the response is coming from the
|
||||||
server and not a malicious third party (<a href="https://owasp.org/www-community/attacks/csrf" target="_blank">CSRF attack</a>).
|
server and not a malicious third party (<a href="https://owasp.org/www-community/attacks/csrf" target="_blank">CSRF attack</a>).
|
||||||
</p>
|
</p>
|
||||||
</li>
|
</li> -->
|
||||||
<li class="collection-item">
|
<li class="collection-item">
|
||||||
<p><b><span class="emphasis">code_challenge</span>=<span id="codeChallenge"></span></b></p>
|
<p><b><span class="emphasis">code_challenge</span>=<span id="codeChallenge"></span></b></p>
|
||||||
<p>
|
<p>
|
||||||
@@ -159,7 +159,7 @@
|
|||||||
+ "&" + "client_id=" + getClientId()
|
+ "&" + "client_id=" + getClientId()
|
||||||
+ "&" + "redirect_uri=" + redirectUri
|
+ "&" + "redirect_uri=" + redirectUri
|
||||||
+ "&" + "scope=" + scope
|
+ "&" + "scope=" + scope
|
||||||
+ "&" + "state=" + state
|
//+ "&" + "state=" + state
|
||||||
+ "&" + "code_challenge=" + codeChallenge
|
+ "&" + "code_challenge=" + codeChallenge
|
||||||
+ "&" + "code_challenge_method=S256";
|
+ "&" + "code_challenge_method=S256";
|
||||||
}
|
}
|
||||||
@@ -170,7 +170,7 @@
|
|||||||
+ "&client_id=" + getClientId() + "\n"
|
+ "&client_id=" + getClientId() + "\n"
|
||||||
+ "&redirect_uri=" + redirectUri + "\n"
|
+ "&redirect_uri=" + redirectUri + "\n"
|
||||||
+ "&scope=" + scope + "\n"
|
+ "&scope=" + scope + "\n"
|
||||||
+ "&state=" + state + "\n"
|
//+ "&state=" + state + "\n"
|
||||||
+ "&code_challenge=" + codeChallenge + "\n"
|
+ "&code_challenge=" + codeChallenge + "\n"
|
||||||
+ "&code_challenge_method=S256";
|
+ "&code_challenge_method=S256";
|
||||||
|
|
||||||
@@ -191,7 +191,7 @@
|
|||||||
|
|
||||||
const responseType = "code";
|
const responseType = "code";
|
||||||
const redirectUri = getRedirectUri();
|
const redirectUri = getRedirectUri();
|
||||||
const scope = "photos%20files";
|
const scope = "photos files";
|
||||||
const state = generateSessionState();
|
const state = generateSessionState();
|
||||||
const codeChallenge = getCookie("code_challenge");
|
const codeChallenge = getCookie("code_challenge");
|
||||||
|
|
||||||
|
|||||||
@@ -51,7 +51,7 @@
|
|||||||
Build the authorization URL and redirect the user to the authorization server
|
Build the authorization URL and redirect the user to the authorization server
|
||||||
</div>
|
</div>
|
||||||
<div class="col s3 circle-text">
|
<div class="col s3 circle-text">
|
||||||
After the user is redirected back to the client, verify the state
|
The user is redirected back to the client
|
||||||
</div>
|
</div>
|
||||||
<div class="col s3 circle-text">
|
<div class="col s3 circle-text">
|
||||||
Exchange the authorization code and code verifier for an access token
|
Exchange the authorization code and code verifier for an access token
|
||||||
@@ -63,14 +63,14 @@
|
|||||||
<div class="card horizontal">
|
<div class="card horizontal">
|
||||||
<div class="card-stacked">
|
<div class="card-stacked">
|
||||||
<div class="card-content">
|
<div class="card-content">
|
||||||
<h6>3. Verify the state parameter</h6>
|
<h6>3. Parse response</h6>
|
||||||
<p>
|
<p>
|
||||||
You have now been redirected back to the application, to the page that was specified in the <b>redirect-url</b> parameter. In the URL you can notice, that there are addtional query parameters:
|
You have now been redirected back to the application, to the page that was specified in the <b>redirect-url</b> parameter. In the URL you can notice, that there are addtional query parameters:
|
||||||
</p>
|
</p>
|
||||||
<pre class="code-block"><code id="queryParams"></code></pre>
|
<pre class="code-block"><code id="queryParams"></code></pre>
|
||||||
<p>Let's break it down...</p>
|
<p>Let's break it down...</p>
|
||||||
<ul class="collection">
|
<ul class="collection">
|
||||||
<li class="collection-item">
|
<li class="collection-item has-state">
|
||||||
<p><b><span class="emphasis">state</span>=<span id="state"></span></b></p>
|
<p><b><span class="emphasis">state</span>=<span id="state"></span></b></p>
|
||||||
<p>
|
<p>
|
||||||
The state parameter is an opaque value used by the client to maintain state between the request and the callback.
|
The state parameter is an opaque value used by the client to maintain state between the request and the callback.
|
||||||
@@ -93,11 +93,11 @@
|
|||||||
</p>
|
</p>
|
||||||
</li>
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
<p>
|
<p class="has-state">
|
||||||
Now we have everything necessary to obtain token for the user. But is the state we have sent (<b><span id="sent-state"></span></b>) equivalent to
|
Now we have everything necessary to obtain token for the user. But is the state we have sent (<b><span id="sent-state"></span></b>) equivalent to
|
||||||
the one we received back (<b><span id="received-state"></span></b>)?
|
the one we received back (<b><span id="received-state"></span></b>)?
|
||||||
</p>
|
</p>
|
||||||
<div class="row flow-submit-container">
|
<div class="row flow-submit-container has-state">
|
||||||
<div class="col m6 s12" style="margin-bottom: 5px;">
|
<div class="col m6 s12" style="margin-bottom: 5px;">
|
||||||
<a class="waves-effect waves-light btn btn-success full-width" onclick="proceedToNextStep()">States are matching</a>
|
<a class="waves-effect waves-light btn btn-success full-width" onclick="proceedToNextStep()">States are matching</a>
|
||||||
</div>
|
</div>
|
||||||
@@ -105,6 +105,10 @@
|
|||||||
<a class="waves-effect waves-light btn btn-error full-width" href="/flow/code">States are not matching</a>
|
<a class="waves-effect waves-light btn btn-error full-width" href="/flow/code">States are not matching</a>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<div class="row flow-submit-container no-state">
|
||||||
|
<a id="get-token-btn" class="waves-effect waves-light btn full-width" onClick="proceedToNextStep()">Continue</a>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -124,15 +128,18 @@
|
|||||||
const state = urlParams.get('state');
|
const state = urlParams.get('state');
|
||||||
const sentState = getCookie("pkce-state");
|
const sentState = getCookie("pkce-state");
|
||||||
|
|
||||||
if (!code || !state || !sentState) {
|
// if (!code || !state || !sentState) {
|
||||||
window.location = "/flow/expired";
|
// window.location = "/flow/expired";
|
||||||
}
|
// }
|
||||||
|
|
||||||
$("#queryParams").text(window.location.search)
|
$("#queryParams").text(window.location.search)
|
||||||
$("#state").text(state);
|
$("#state").text(state);
|
||||||
$("#sent-state").text(sentState);
|
$("#sent-state").text(sentState);
|
||||||
$("#received-state").text(state);
|
$("#received-state").text(state);
|
||||||
$("#code").text(code);
|
$("#code").text(code);
|
||||||
|
|
||||||
|
$(".has-state").toggle(!!state);
|
||||||
|
$(".no-state").toggle(!state);
|
||||||
|
|
||||||
function proceedToNextStep() {
|
function proceedToNextStep() {
|
||||||
window.location.href = "/flow/pkce-4" + window.location.search;
|
window.location.href = "/flow/pkce-4" + window.location.search;
|
||||||
|
|||||||
@@ -51,7 +51,7 @@
|
|||||||
Build the authorization URL and redirect the user to the authorization server
|
Build the authorization URL and redirect the user to the authorization server
|
||||||
</div>
|
</div>
|
||||||
<div class="col s3 circle-text">
|
<div class="col s3 circle-text">
|
||||||
After the user is redirected back to the client, verify the state
|
The user is redirected back to the client
|
||||||
</div>
|
</div>
|
||||||
<div class="col s3 circle-text">
|
<div class="col s3 circle-text">
|
||||||
Exchange the authorization code and code verifier for an access token
|
Exchange the authorization code and code verifier for an access token
|
||||||
|
|||||||
@@ -50,7 +50,7 @@
|
|||||||
Build the authorization URL and redirect the user to the authorization server
|
Build the authorization URL and redirect the user to the authorization server
|
||||||
</div>
|
</div>
|
||||||
<div class="col s3 circle-text">
|
<div class="col s3 circle-text">
|
||||||
After the user is redirected back to the client, verify the state
|
The user is redirected back to the client
|
||||||
</div>
|
</div>
|
||||||
<div class="col s3 circle-text">
|
<div class="col s3 circle-text">
|
||||||
Exchange the authorization code and code verifier for an access token
|
Exchange the authorization code and code verifier for an access token
|
||||||
|
|||||||
@@ -44,7 +44,7 @@
|
|||||||
Build the authorization URL and redirect the user to the authorization server
|
Build the authorization URL and redirect the user to the authorization server
|
||||||
</div>
|
</div>
|
||||||
<div class="col s4 circle-text">
|
<div class="col s4 circle-text">
|
||||||
After the user is redirected back to the client, verify that the state matches
|
The user is redirected back to the client
|
||||||
</div>
|
</div>
|
||||||
<div class="col s4 circle-text">
|
<div class="col s4 circle-text">
|
||||||
Exchange the authorization code for an access token
|
Exchange the authorization code for an access token
|
||||||
@@ -56,7 +56,7 @@
|
|||||||
<div class="card horizontal">
|
<div class="card horizontal">
|
||||||
<div class="card-stacked">
|
<div class="card-stacked">
|
||||||
<div class="card-content">
|
<div class="card-content">
|
||||||
<h6>2. Verify the state parameter</h6>
|
<h6>2. Parse response</h6>
|
||||||
<p>
|
<p>
|
||||||
You have now been redirected back to the application, to the page that was specified in the <b>redirect-url</b> parameter. In the URL
|
You have now been redirected back to the application, to the page that was specified in the <b>redirect-url</b> parameter. In the URL
|
||||||
you can notice, that there are addtional query parameters:
|
you can notice, that there are addtional query parameters:
|
||||||
@@ -64,7 +64,7 @@
|
|||||||
<pre class="code-block"><code id="queryParams"></code></pre>
|
<pre class="code-block"><code id="queryParams"></code></pre>
|
||||||
<p>Let's break it down...</p>
|
<p>Let's break it down...</p>
|
||||||
<ul class="collection">
|
<ul class="collection">
|
||||||
<li class="collection-item">
|
<li class="collection-item has-state">
|
||||||
<p><b><span class="emphasis">state</span>=<span id="state"></span></b></p>
|
<p><b><span class="emphasis">state</span>=<span id="state"></span></b></p>
|
||||||
<p>
|
<p>
|
||||||
The state parameter is an opaque value used by the client to maintain state between the request and the callback.
|
The state parameter is an opaque value used by the client to maintain state between the request and the callback.
|
||||||
@@ -82,10 +82,10 @@
|
|||||||
</p>
|
</p>
|
||||||
</li>
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
<p>
|
<p class="has-state">
|
||||||
Now we have everything necessary to obtain token for the user. But is the state we have sent (<b><span id="sent-state"></span></b>) equivalent to the one we received back (<b><span id="received-state"></span></b>)?
|
Now we have everything necessary to obtain token for the user. But is the state we have sent (<b><span id="sent-state"></span></b>) equivalent to the one we received back (<b><span id="received-state"></span></b>)?
|
||||||
</p>
|
</p>
|
||||||
<div class="row flow-submit-container">
|
<div class="row flow-submit-container has-state">
|
||||||
<div class="col m6 s12" style="margin-bottom: 5px;">
|
<div class="col m6 s12" style="margin-bottom: 5px;">
|
||||||
<a class="waves-effect waves-light btn btn-success full-width" onclick="proceedToNextStep()">States are matching</a>
|
<a class="waves-effect waves-light btn btn-success full-width" onclick="proceedToNextStep()">States are matching</a>
|
||||||
</div>
|
</div>
|
||||||
@@ -93,6 +93,10 @@
|
|||||||
<a class="waves-effect waves-light btn btn-error full-width" href="/flow/code">States are not matching</a>
|
<a class="waves-effect waves-light btn btn-error full-width" href="/flow/code">States are not matching</a>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<div class="row flow-submit-container no-state">
|
||||||
|
<a id="get-token-btn" class="waves-effect waves-light btn full-width" onClick="proceedToNextStep()">Continue</a>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -112,9 +116,9 @@
|
|||||||
const state = urlParams.get("state");
|
const state = urlParams.get("state");
|
||||||
const sentState = getCookie("webauth-state");
|
const sentState = getCookie("webauth-state");
|
||||||
|
|
||||||
if (!code || !state || !sentState) {
|
// if (!code || !state || !sentState) {
|
||||||
window.location = "/flow/expired";
|
// window.location = "/flow/expired";
|
||||||
}
|
// }
|
||||||
|
|
||||||
$("#queryParams").text(window.location.search)
|
$("#queryParams").text(window.location.search)
|
||||||
$("#state").text(state);
|
$("#state").text(state);
|
||||||
@@ -122,6 +126,9 @@
|
|||||||
$("#received-state").text(state);
|
$("#received-state").text(state);
|
||||||
$("#code").text(code);
|
$("#code").text(code);
|
||||||
|
|
||||||
|
$(".has-state").toggle(!!state);
|
||||||
|
$(".no-state").toggle(!state);
|
||||||
|
|
||||||
function proceedToNextStep() {
|
function proceedToNextStep() {
|
||||||
window.location.href = "/flow/webauthn-3" + window.location.search;
|
window.location.href = "/flow/webauthn-3" + window.location.search;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -44,7 +44,7 @@
|
|||||||
Build the authorization URL and redirect the user to the authorization server
|
Build the authorization URL and redirect the user to the authorization server
|
||||||
</div>
|
</div>
|
||||||
<div class="col s4 circle-text">
|
<div class="col s4 circle-text">
|
||||||
After the user is redirected back to the client, verify that the state matches
|
The user is redirected back to the client
|
||||||
</div>
|
</div>
|
||||||
<div class="col s4 circle-text">
|
<div class="col s4 circle-text">
|
||||||
Exchange the authorization code for an access token
|
Exchange the authorization code for an access token
|
||||||
|
|||||||
@@ -44,7 +44,7 @@
|
|||||||
Build the authorization URL and redirect the user to the authorization server
|
Build the authorization URL and redirect the user to the authorization server
|
||||||
</div>
|
</div>
|
||||||
<div class="col s4 circle-text">
|
<div class="col s4 circle-text">
|
||||||
After the user is redirected back to the client, verify that the state matches
|
The user is redirected back to the client
|
||||||
</div>
|
</div>
|
||||||
<div class="col s4 circle-text">
|
<div class="col s4 circle-text">
|
||||||
Exchange the authorization code for an access token
|
Exchange the authorization code for an access token
|
||||||
@@ -58,11 +58,17 @@
|
|||||||
<div class="card-content">
|
<div class="card-content">
|
||||||
<h6>1. Build the Authorization URL</h6>
|
<h6>1. Build the Authorization URL</h6>
|
||||||
<p>
|
<p>
|
||||||
In order to initiate the <b>WebAuthn</b>, we proceed the same way as we would if we would be using <b>Authorization Code Flow</b> we need to build the
|
WebAuthn is not an OAuth grant, but rather a new browser API to facilitate passwordless login.
|
||||||
authorization URL and redirect the user to the authorization server. All the passwordless logic is handled completely by the authorization server. The URL is constructed as follows:
|
</p>
|
||||||
|
<p>It can be used with any grant that renders a login form,
|
||||||
|
such as <a href="/flow/code">Authorization Code Flow</a> or <a href="/flow/dag">Device Authorization Grant</a>, or even outside OAuth for your application's custom login.
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
For this demostration, we'll use an <a href="/flow/code">Authorization Code Flow</a> with a custom URL. In practice, if and when Webauthn is used instead of passwords passwords depends on the Authority Server settings.
|
||||||
|
</p>
|
||||||
</p>
|
</p>
|
||||||
<pre class="code-block"><code id="requestUriExample"></code></pre>
|
<pre class="code-block"><code id="requestUriExample"></code></pre>
|
||||||
<p>Let's break it down...</p>
|
<!-- <p>Let's break it down...</p>
|
||||||
<ul class="collection">
|
<ul class="collection">
|
||||||
<li class="collection-item">
|
<li class="collection-item">
|
||||||
<p><b><span id="baseUrl"></span></b></p>
|
<p><b><span id="baseUrl"></span></b></p>
|
||||||
@@ -111,7 +117,7 @@
|
|||||||
server and not a malicious third party (<a href="https://owasp.org/www-community/attacks/csrf" target="_blank">CSRF attack</a>).
|
server and not a malicious third party (<a href="https://owasp.org/www-community/attacks/csrf" target="_blank">CSRF attack</a>).
|
||||||
</p>
|
</p>
|
||||||
</li>
|
</li>
|
||||||
</ul>
|
</ul> -->
|
||||||
<p>
|
<p>
|
||||||
All that we now need to do is click the button below and perform the <b>Web Authentication Flow</b> on the server. After your account will be successfully verified, you will be redirected back to this playground, to the URL we have specified in the <b>redirect_uri</b> query parameter of the request.
|
All that we now need to do is click the button below and perform the <b>Web Authentication Flow</b> on the server. After your account will be successfully verified, you will be redirected back to this playground, to the URL we have specified in the <b>redirect_uri</b> query parameter of the request.
|
||||||
</p>
|
</p>
|
||||||
@@ -143,7 +149,8 @@
|
|||||||
+ "&" + "client_id=" + getClientId()
|
+ "&" + "client_id=" + getClientId()
|
||||||
+ "&" + "redirect_uri=" + redirectUri
|
+ "&" + "redirect_uri=" + redirectUri
|
||||||
+ "&" + "scope=" + scope
|
+ "&" + "scope=" + scope
|
||||||
+ "&" + "state=" + state;
|
//+ "&" + "state=" + state
|
||||||
|
;
|
||||||
}
|
}
|
||||||
|
|
||||||
function fillExample() {
|
function fillExample() {
|
||||||
@@ -152,7 +159,8 @@
|
|||||||
+ "&client_id=" + getClientId() + "\n"
|
+ "&client_id=" + getClientId() + "\n"
|
||||||
+ "&redirect_uri=" + redirectUri + "\n"
|
+ "&redirect_uri=" + redirectUri + "\n"
|
||||||
+ "&scope=" + scope + "\n"
|
+ "&scope=" + scope + "\n"
|
||||||
+ "&state=" + state;
|
//+ "&state=" + state
|
||||||
|
;
|
||||||
|
|
||||||
$("#requestUriExample").text(requestExample);
|
$("#requestUriExample").text(requestExample);
|
||||||
$("#baseUrl").text(authUrl);
|
$("#baseUrl").text(authUrl);
|
||||||
@@ -172,7 +180,7 @@
|
|||||||
const authUrl = baseUrl + "/passwordless"
|
const authUrl = baseUrl + "/passwordless"
|
||||||
const responseType = "code";
|
const responseType = "code";
|
||||||
const redirectUri = getRedirectUri();
|
const redirectUri = getRedirectUri();
|
||||||
const scope = "photos%20files";
|
const scope = "photos files";
|
||||||
const state = generateSessionState();
|
const state = generateSessionState();
|
||||||
setCookie("webauth-state", state, 5);
|
setCookie("webauth-state", state, 5);
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user