mirror of
https://github.com/ysoftdevs/oauth-playground-client.git
synced 2026-05-06 07:53:31 +02:00
Ability to say that states are not matching
This commit is contained in:
@@ -42,7 +42,7 @@ body {
|
||||
|
||||
/* Success Color */
|
||||
.btn-success {
|
||||
background-color: #33FF66;
|
||||
background-color: #2e663c;
|
||||
}
|
||||
|
||||
/* Text Color for Primary buttons */
|
||||
|
||||
@@ -74,10 +74,14 @@
|
||||
the structure.</p>
|
||||
</li>
|
||||
</ul>
|
||||
<p>Now we have everything necessary to obtain token for the user. But is the state we have sent equivalent to the one we received back?</p>
|
||||
<p>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>
|
||||
<div class="row flow-submit-container">
|
||||
<a class="waves-effect waves-light btn full-width"
|
||||
onclick="proceedToNextStep()">States are matching</a>
|
||||
<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>
|
||||
</div>
|
||||
<div class="col m6 s12">
|
||||
<a class="waves-effect waves-light btn btn-error full-width" href="/flow/code">States are not matching</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -91,14 +95,18 @@
|
||||
</main>
|
||||
<footer class="page-footer"></footer>
|
||||
<script src="../js/load-layout.js"></script>
|
||||
<script src="../js/cookies.js"></script>
|
||||
<script>
|
||||
$("#queryParams").text(window.location.search)
|
||||
|
||||
const urlParams = new URLSearchParams(window.location.search);
|
||||
const code = urlParams.get('code');
|
||||
const state = urlParams.get('state');
|
||||
const code = urlParams.get("code");
|
||||
const state = urlParams.get("state");
|
||||
const sentState = getCookie("state");
|
||||
|
||||
$("#state").text(state);
|
||||
$("#sent-state").text(sentState);
|
||||
$("#received-state").text(state);
|
||||
$("#code").text(code);
|
||||
|
||||
function proceedToNextStep() {
|
||||
|
||||
@@ -122,6 +122,7 @@
|
||||
</main>
|
||||
<footer class="page-footer"></footer>
|
||||
<script src="../js/load-layout.js"></script>
|
||||
<script src="../js/cookies.js"></script>
|
||||
<script src="../js/env-config.js"></script>
|
||||
<script>
|
||||
function generateSessionState () {
|
||||
@@ -163,6 +164,7 @@
|
||||
const scope = "offline_access";
|
||||
const state = generateSessionState();
|
||||
|
||||
setCookie("state", state, 5);
|
||||
fillExample();
|
||||
$("#sendRequestBtn").attr("href", constructRequestUrl());
|
||||
</script>
|
||||
|
||||
@@ -186,6 +186,7 @@
|
||||
const state = generateSessionState();
|
||||
const codeChallenge = getCookie("code_challenge");
|
||||
|
||||
setCookie("pkce-state", state, 5);
|
||||
fillExample();
|
||||
$("#sendRequestBtn").attr("href", constructRequestUrl());
|
||||
</script>
|
||||
|
||||
@@ -76,13 +76,6 @@
|
||||
for CSRF protection.</p>
|
||||
</p>
|
||||
</li>
|
||||
<li class="collection-item">
|
||||
<p><b><span class="emphasis">session_state</span>=<span id="sessionState"></span></b></p>
|
||||
<p>The session state parameter is not a core part of the OAuth 2.0 specification, but it is used in OpenID Connect (OIDC)
|
||||
to represent the state of the end user's session at the Authorization Server.
|
||||
The client can use this value to help manage user sessions or to detect when the user's session at the Authorization
|
||||
Server changes (for example, if the user logs out).</p>
|
||||
</li>
|
||||
<li class="collection-item">
|
||||
<p><b><span class="emphasis">code</span>=<span id="code"></span></b></p>
|
||||
<p>The code parameter contains the actual authorization code. This is a temporary code that the client can exchange for an
|
||||
@@ -91,10 +84,17 @@
|
||||
the structure.</p>
|
||||
</li>
|
||||
</ul>
|
||||
<p>Now we have everything necessary to obtain token for the user. But is the state we have sent equivalent to the one we received back?</p>
|
||||
<p>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>
|
||||
<div class="row flow-submit-container">
|
||||
<a class="waves-effect waves-light btn full-width"
|
||||
onclick="proceedToNextStep()">States are matching</a>
|
||||
<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>
|
||||
</div>
|
||||
<div class="col m6 s12">
|
||||
<a class="waves-effect waves-light btn btn-error full-width" href="/flow/code">States are not matching</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -108,16 +108,18 @@
|
||||
</main>
|
||||
<footer class="page-footer"></footer>
|
||||
<script src="../js/load-layout.js"></script>
|
||||
<script src="../js/cookies.js"></script>
|
||||
<script>
|
||||
$("#queryParams").text(window.location.search)
|
||||
|
||||
const urlParams = new URLSearchParams(window.location.search);
|
||||
const code = urlParams.get('code');
|
||||
const state = urlParams.get('state');
|
||||
const sessionState = urlParams.get('session_state');
|
||||
const sentState = getCookie("pkce-state");
|
||||
|
||||
$("#state").text(state);
|
||||
$("#sessionState").text(sessionState);
|
||||
$("#sent-state").text(sentState);
|
||||
$("#received-state").text(state);
|
||||
$("#code").text(code);
|
||||
|
||||
function proceedToNextStep() {
|
||||
|
||||
192
src/flow/webauthn.html
Normal file
192
src/flow/webauthn.html
Normal file
@@ -0,0 +1,192 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>OAuth 2.0 Playground - Authorization Code Flow</title>
|
||||
<meta name="description"
|
||||
content="Dive deep into the Authorization Code Flow with our interactive guide. Understand its workings, best practices, and its role in OAuth for secure user authentication. Ideal for developers aiming for robust web app integrations." />
|
||||
<link rel="icon" href="../favicon.ico" type="image/x-icon">
|
||||
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/materialize/1.0.0/css/materialize.min.css">
|
||||
<link type="text/css" rel="stylesheet" href="../css/style.css" />
|
||||
<link rel="preconnect" href="https://fonts.googleapis.com" />
|
||||
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin />
|
||||
<link rel="stylesheet"
|
||||
href="https://fonts.googleapis.com/css2?family=Roboto:wght@300;400;500;600;700&display=swap" />
|
||||
<link rel="stylesheet" href="https://fonts.googleapis.com/icon?family=Material+Icons" />
|
||||
<script src="https://code.jquery.com/jquery-3.6.0.min.js"></script>
|
||||
<script src="https://cdnjs.cloudflare.com/ajax/libs/materialize/1.0.0/js/materialize.min.js"></script>
|
||||
<script async src="https://www.googletagmanager.com/gtag/js?id=G-CVH4GP5T69"></script>
|
||||
<script src="../js/analytics.js"></script>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<header id="page-header"></header>
|
||||
<main>
|
||||
<div class="container">
|
||||
<div class="section">
|
||||
<h3 class="header centered">WebAuthn</h3>
|
||||
<div class="circle-container circle-3">
|
||||
<div class="circle">
|
||||
1
|
||||
</div>
|
||||
<div class="line line-inactive"></div>
|
||||
<div class="circle circle-inactive">
|
||||
2
|
||||
</div>
|
||||
<div class="line line-inactive"></div>
|
||||
<div class="circle circle-inactive">
|
||||
3
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col s4 circle-text">
|
||||
Build the authorization URL and redirect the user to the authorization server
|
||||
</div>
|
||||
<div class="col s4 circle-text">
|
||||
After the user is redirected back to the client, verify that the state matches
|
||||
</div>
|
||||
<div class="col s4 circle-text">
|
||||
Exchange the authorization code for an access token
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="section">
|
||||
<div class="col s12 m7">
|
||||
<div class="card horizontal">
|
||||
<div class="card-stacked">
|
||||
<div class="card-content">
|
||||
<h6>1. Build the Authorization URL</h6>
|
||||
<p>
|
||||
In order to initiate the <b>Authorization Code Flow</b>, we need to build the
|
||||
authorization URL
|
||||
and redirect the user to the authorization server. The URL is constructed as
|
||||
follows:
|
||||
</p>
|
||||
<pre class="code-block"><code id="requestUriExample"></code></pre>
|
||||
<p>Let's break it down...</p>
|
||||
<ul class="collection">
|
||||
<li class="collection-item">
|
||||
<p><b><span id="baseUrl"></span></b>
|
||||
</p>
|
||||
<p>URL of the authorization endpoint on the server. How is this path constructed
|
||||
will
|
||||
differ between OAuth providers (such as Keycloak, Okta, etc.).
|
||||
</p>
|
||||
</li>
|
||||
<li class="collection-item">
|
||||
<p><b><span class="emphasis">response_type</span>=<span
|
||||
id="responseType"></span></b></p>
|
||||
<p>OAuth 2.0 response type. In this case, we are using the Authorization Code
|
||||
flow, so
|
||||
we are requesting the authorization <b>code</b>.</p>
|
||||
</li>
|
||||
<li class="collection-item">
|
||||
<p><b><span class="emphasis">client_id</span>=<span id="clientId"></span></b>
|
||||
</p>
|
||||
<p>Client ID of the application. This is a public identifier for the client, and
|
||||
it is
|
||||
used by the authorization server to identify the application
|
||||
when redirecting the user back to the client.</p>
|
||||
</li>
|
||||
<li class="collection-item">
|
||||
<p><b><span class="emphasis">redirect_uri</span>=<span
|
||||
id="redirectUri"></span></b></p>
|
||||
<p>Redirect URI of the client. This is the URL that the authorization server
|
||||
will
|
||||
redirect the user back to after the user has logged in and
|
||||
granted permissions. The redirect URI must match one of the URIs registered
|
||||
for the
|
||||
client ID.</p>
|
||||
</li>
|
||||
<li class="collection-item">
|
||||
<p><b><span class="emphasis">scope</span>=<span id="scope"></span></b></p>
|
||||
<p>Scopes requested by the client. Scopes are used to limit the access of the
|
||||
access
|
||||
token. In this case, we are requesting the <b>offline_access</b> scope,
|
||||
which allows the client to obtain a refresh token.</p>
|
||||
</li>
|
||||
<li class="collection-item">
|
||||
<p><b><span class="emphasis">state</span>=<span id="state"></span></b></p>
|
||||
<p>State parameter. This is an <b>optional parameter</b> that the client can use
|
||||
to maintain
|
||||
state between the request and callback. The authorization
|
||||
server includes this parameter when 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>).</p>
|
||||
</li>
|
||||
</ul>
|
||||
<p>All that we now need to do is click the button below and login with our credentials.
|
||||
For the purposes of this
|
||||
playground we already took the liberty to create <b>user</b> with password
|
||||
<b>user</b> for you. After your credentials are 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>
|
||||
<div class="row flow-submit-container">
|
||||
<a id="sendRequestBtn" class="waves-effect waves-light btn full-width"
|
||||
href="#">Authenticate</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="section centered">
|
||||
<a href="/">[ Take me home ]</a>
|
||||
</div>
|
||||
</div>
|
||||
</main>
|
||||
<footer class="page-footer"></footer>
|
||||
<script src="../js/load-layout.js"></script>
|
||||
<script src="../js/env-config.js"></script>
|
||||
<script>
|
||||
const authUrl = baseUrl + "/passwordless"
|
||||
|
||||
function generateSessionState() {
|
||||
return Math.random().toString(36).substring(2, 15) + Math.random().toString(36).substring(2, 15);
|
||||
}
|
||||
|
||||
function constructRequestUrl() {
|
||||
return authUrl
|
||||
+ "?" + "response_type=" + responseType
|
||||
+ "&" + "client_id=" + getClientId()
|
||||
+ "&" + "redirect_uri=" + redirectUri
|
||||
+ "&" + "scope=" + scope
|
||||
+ "&" + "state=" + state;
|
||||
}
|
||||
|
||||
function fillExample() {
|
||||
const requestExample = authUrl + "\n"
|
||||
+ "?response_type=" + responseType + "\n"
|
||||
+ "&client_id=" + getClientId() + "\n"
|
||||
+ "&redirect_uri=" + redirectUri + "\n"
|
||||
+ "&scope=" + scope + "\n"
|
||||
+ "&state=" + state;
|
||||
|
||||
$("#requestUriExample").text(requestExample);
|
||||
$("#baseUrl").text(authUrl);
|
||||
$("#responseType").text(responseType);
|
||||
$("#clientId").text(getClientId());
|
||||
$("#redirectUri").text(redirectUri);
|
||||
$("#scope").text(scope);
|
||||
$("#state").text(state);
|
||||
}
|
||||
|
||||
function getRedirectUri() {
|
||||
return window.location.protocol + "//" + window.location.host + "/flow/code-2";
|
||||
}
|
||||
|
||||
const responseType = "code";
|
||||
const redirectUri = getRedirectUri();
|
||||
const scope = "offline_access";
|
||||
const state = generateSessionState();
|
||||
|
||||
fillExample();
|
||||
$("#sendRequestBtn").attr("href", constructRequestUrl());
|
||||
</script>
|
||||
</body>
|
||||
|
||||
</html>
|
||||
@@ -105,7 +105,7 @@
|
||||
<div class="card horizontal">
|
||||
<div class="card-stacked flow-card">
|
||||
<div class="card-content">
|
||||
<h5>WebAuthN</h5>
|
||||
<h5>WebAuthn</h5>
|
||||
<p class="justified">This protocol leverages public key cryptography and allows users to authenticate
|
||||
using biometrics, mobile devices, or
|
||||
FIDO security keys, instead of traditional passwords. When a user registers with a website, a unique
|
||||
@@ -118,8 +118,8 @@
|
||||
reliance on easily
|
||||
compromised passwords and defending against phishing attacks.</p>
|
||||
</div>
|
||||
<div class="card-action underConstruction">
|
||||
<i class="tiny material-icons">build</i> Under construction
|
||||
<div class="card-action">
|
||||
<a href="/flow/webauthn">Try it</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -12,4 +12,10 @@
|
||||
<changefreq>weekly</changefreq>
|
||||
<priority>0.8</priority>
|
||||
</url>
|
||||
<url>
|
||||
<loc>https://oauth-playground.online/flow/dag</loc>
|
||||
<lastmod>2023-09-26</lastmod>
|
||||
<changefreq>weekly</changefreq>
|
||||
<priority>0.8</priority>
|
||||
</url>
|
||||
</urlset>
|
||||
|
||||
Reference in New Issue
Block a user