Skip to content

Commit 72cf3f6

Browse files
authored
Merge pull request #870 from jsonwebtoken/update-introduction-page
Add sidebar navigation to introduction page
2 parents c011c3f + d2d5054 commit 72cf3f6

File tree

10 files changed

+217
-34
lines changed

10 files changed

+217
-34
lines changed

src/features/introduction/components/introduction-article/introduction-article.component.tsx

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,8 @@
33
import React from "react";
44
import { getIntroductionContent } from "@/features/localization/services/ui-language-content.service";
55
import { ArticleComponent } from "@/features/common/components/article/article.component";
6+
import styles from "./introduction-article.module.scss";
7+
import { SidebarNavComponent } from "../sidebar-nav/sidebar-nav.component";
68

79
interface IntroductionArticleComponentProps {
810
languageCode: string;
@@ -11,11 +13,12 @@ interface IntroductionArticleComponentProps {
1113
export const IntroductionArticleComponent: React.FC<
1214
IntroductionArticleComponentProps
1315
> = ({ languageCode }) => {
14-
const { Component: Introduction } = getIntroductionContent({ languageCode });
16+
const Introduction = getIntroductionContent({ languageCode });
1517

1618
return (
17-
<ArticleComponent>
18-
<Introduction />
19-
</ArticleComponent>
19+
<div className={styles.container}>
20+
<SidebarNavComponent languageCode={languageCode} />
21+
<ArticleComponent>{Introduction}</ArticleComponent>
22+
</div>
2023
);
2124
};
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
@use "@/libs/theme/styles/variables" as *;
2+
3+
.container {
4+
min-height: 100vh;
5+
display: flex;
6+
flex-direction: column;
7+
8+
@media #{$breakpoint-dimension-sm} {
9+
flex-direction: row;
10+
}
11+
}
Lines changed: 75 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,75 @@
1+
"use client";
2+
3+
import React, { useEffect, useState } from "react";
4+
import { getIntroductionDictionary } from "@/features/localization/services/language-dictionary.service";
5+
import styles from "./sidebar-nav.module.scss";
6+
import clsx from "clsx";
7+
8+
interface SidebarNavComponentProps {
9+
languageCode: string;
10+
}
11+
12+
const scrollToElementWithOffset = (id: string, offset = 0) => {
13+
const element = document.getElementById(id);
14+
if (element) {
15+
const y = element.getBoundingClientRect().top + window.pageYOffset + offset;
16+
window.scrollTo({ top: y, behavior: "smooth" });
17+
}
18+
};
19+
20+
export const SidebarNavComponent: React.FC<SidebarNavComponentProps> = ({
21+
languageCode,
22+
}) => {
23+
const introductionDictionary = getIntroductionDictionary(languageCode);
24+
const headings = introductionDictionary.content.headings;
25+
const [activeId, setActiveId] = useState<string | null>(null);
26+
27+
useEffect(() => {
28+
const observer = new IntersectionObserver(
29+
(entries) => {
30+
entries.forEach((entry) => {
31+
if (entry.isIntersecting) {
32+
const id = entry.target.id;
33+
setActiveId(id);
34+
history.replaceState(null, "", `#${id}`);
35+
}
36+
});
37+
},
38+
{
39+
rootMargin: "0px 0px -40% 0px",
40+
threshold: 1,
41+
}
42+
);
43+
const elements = headings
44+
.map((heading) => document.getElementById(heading.id))
45+
.filter(Boolean) as HTMLElement[];
46+
elements.forEach((el) => observer.observe(el));
47+
return () => {
48+
elements.forEach((el) => observer.unobserve(el));
49+
};
50+
}, [headings]);
51+
52+
const handleClick = (id: string) => {
53+
scrollToElementWithOffset(id, -120);
54+
history.replaceState(null, "", `#${id}`);
55+
};
56+
57+
return (
58+
<div className={styles.container}>
59+
<ul className={styles.list}>
60+
{introductionDictionary.content.headings.map((heading, index) => (
61+
<li
62+
key={index}
63+
className={clsx(
64+
styles.title,
65+
activeId === heading.id && styles.title__active
66+
)}
67+
onClick={() => handleClick(heading.id)}
68+
>
69+
{heading.title}
70+
</li>
71+
))}
72+
</ul>
73+
</div>
74+
);
75+
};
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
@use "@/libs/theme/styles/variables" as *;
2+
3+
.container {
4+
display:none;
5+
@media #{$breakpoint-dimension-sm} {
6+
display: inline-block;
7+
height: 100vh;
8+
position: sticky;
9+
color: var(--color_fg_link);
10+
flex-shrink: 0;
11+
top: 0;
12+
padding: 160px 30px 0px;
13+
margin-bottom: 100px;
14+
border-right: 1px solid var(--color_border_bold);
15+
max-width: 250px;
16+
overflow-y: auto;
17+
}
18+
}
19+
20+
.title {
21+
margin-bottom: 36px;
22+
padding-right: 8px;
23+
cursor: pointer;
24+
}
25+
26+
.title__active {
27+
color: var(--color_fg_selected);
28+
border-bottom: 1px solid var(--color_border_selected);
29+
}
30+
31+
.list {
32+
list-style-type: none;
33+
}

src/features/introduction/docs/en.introduction.mdx

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,19 @@
11
import { MdxAnchorComponent } from "@/features/common/components/markdown/mdx-anchor.component";
22
import { MarkdownImage } from "@/features/common/components/markdown/markdown-image";
33

4-
## What is JSON Web Token?
4+
<h2 id={props.headings[0].id}>{props.headings[0].title}</h2>
55

66
JSON Web Token (JWT) is an open standard (<MdxAnchorComponent type="external" href="https://tools.ietf.org/html/rfc7519">RFC 7519</MdxAnchorComponent>) that defines a compact and self-contained way for securely transmitting information between parties as a JSON object. This information can be verified and trusted because it is digitally signed. JWTs can be signed using a secret (with the **HMAC** algorithm) or a public/private key pair using **RSA** or **ECDSA**.
77

88
Although JWTs can be encrypted to also provide secrecy between parties, we will focus on *signed* tokens. Signed tokens can verify the *integrity* of the claims contained within it, while encrypted tokens *hide* those claims from other parties. When tokens are signed using public/private key pairs, the signature also certifies that only the party holding the private key is the one that signed it.
99

10-
## When should you use JSON Web Tokens?
10+
<h2 id={props.headings[1].id}>{props.headings[1].title}</h2>
1111
Here are some scenarios where JSON Web Tokens are useful:
1212

1313
- **Authorization**: This is the most common scenario for using JWT. Once the user is logged in, each subsequent request will include the JWT, allowing the user to access routes, services, and resources that are permitted with that token. Single Sign On is a feature that widely uses JWT nowadays because of its small overhead and its ability to be easily used across different domains.
1414
- **Information Exchange**: JSON Web Tokens are a good way of securely transmitting information between parties. Because JWTs can be signed—for example, using public/private key pairs—you can be sure the senders are who they say they are. Additionally, as the signature is calculated using the header and the payload, you can also verify that the content hasn't been tampered with.
1515

16-
## What is the JSON Web Token structure?
16+
<h2 id={props.headings[2].id}>{props.headings[2].title}</h2>
1717
In its compact form, JSON Web Tokens consist of three parts separated by dots (`.`), which are:
1818

1919
- Header
@@ -93,7 +93,7 @@ If you want to play with JWT and put these concepts into practice, you can use <
9393

9494
<MarkdownImage src="https://cdn.auth0.com/website/jwt/introduction/debugger.png" alt="JWT.io Debugger" />
9595

96-
## How do JSON Web Tokens work?
96+
<h2 id={props.headings[3].id}>{props.headings[3].title}</h2>
9797
In authentication, when the user successfully logs in using their credentials, a JSON Web Token will be returned. Since tokens are credentials, great care must be taken to prevent security issues. In general, you should not keep tokens longer than required.
9898

9999
You also <MdxAnchorComponent type="external" href="https://cheatsheetseries.owasp.org/cheatsheets/HTML5_Security_Cheat_Sheet.html#local-storage">should not store sensitive session data in browser storage due to lack of security</MdxAnchorComponent>.
@@ -120,7 +120,7 @@ The following diagram shows how a JWT is obtained and used to access APIs or res
120120

121121
Do note that with signed tokens, all the information contained within the token is exposed to users or other parties, even though they are unable to change it. This means you should not put secret information within the token.
122122

123-
## Why should we use JSON Web Tokens?
123+
<h2 id={props.headings[4].id}>{props.headings[4].title}</h2>
124124

125125
Let's talk about the benefits of **JSON Web Tokens (JWT)** when compared to **Simple Web Tokens (SWT)** and **Security Assertion Markup Language Tokens (SAML)**.
126126

@@ -138,7 +138,7 @@ _Comparison of the length of an encoded JWT and an encoded SAML_
138138

139139
If you want to read more about JSON Web Tokens and even start using them to perform authentication in your own applications, browse to the <MdxAnchorComponent type="external" href="http://auth0.com/learn/json-web-tokens">JSON Web Token landing page</MdxAnchorComponent> at Auth0.
140140

141-
## Difference Between Validating and Verifying a JWT
141+
<h2 id={props.headings[5].id}>{props.headings[5].title}</h2>
142142

143143
JSON Web Token (JWT) validation and verification are crucial for security, but they address slightly different aspects of JWT security: validation ensures the token is well-formed and contains enforceable claims; verification ensures the token is genuine and unmodified.
144144

@@ -165,7 +165,7 @@ You verify a JWT to make sure the token hasn't been altered maliciously and come
165165
In many systems, these steps are often combined into what might be colloquially called "JWT verification" which encompasses both validation and verification for comprehensive security checks. Nonetheless, their distinction remains.
166166

167167

168-
## Difference Between Decoding and Encoding a JWT
168+
<h2 id={props.headings[6].id}>{props.headings[6].title}</h2>
169169

170170
Encoding a JWT involves transforming the header and payload into a compact, URL-safe format. The header, which states the signing algorithm and token type, and the payload, which includes claims like subject, expiration, and issue time, are both converted to JSON then Base64URL encoded. These encoded parts are then concatenated with a dot, after which a signature is generated using the algorithm specified in the header with a secret or private key. This signature is also Base64URL encoded, resulting in the final JWT string that represents the token in a format suitable for transmission or storage.
171171

src/features/introduction/docs/ja.introduction.mdx

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,19 @@
11
import { MdxAnchorComponent } from "@/features/common/components/markdown/mdx-anchor.component";
22
import { MarkdownImage } from "@/features/common/components/markdown/markdown-image";
33

4-
## JSON Web Tokenとは?
4+
<h2 id={props.headings[0].id}>{props.headings[0].title}</h2>
55

66
JSON Web Token (JWT) は標準規格(<MdxAnchorComponent type="external" href="https://tools.ietf.org/html/rfc7519">RFC 7519</MdxAnchorComponent>)で定義されています。この仕様は認証、認可の情報をJSON形式でシステム間で安全にやりとりする際に使用できる、コンパクトで自己完結型のフォーマットを定義しています。デジタル署名を付与することもできるため、検証可能で信頼がおけます。JWTへの署名には共通鍵を使用するHMACアルゴリズムあるいは、公開鍵/秘密鍵ペアを使用するRSAまたはECDSAアルゴリズムを使用できます。
77

88
JWTは機密性を保つために暗号化することもできますが、ここでは 署名されたJWT に焦点を当てます。署名されたJWTは完全性を検証でき、暗号化されたトークンは内容を他者から隠すことができます。JWTが秘密鍵を用いて署名された場合、その署名は公開鍵を使うことで、秘密鍵を持つ当事者だけがそのJWTに署名した者であることが確認できます。
99

10-
## JSON Web Tokenはいつ使用すべきか?
10+
<h2 id={props.headings[1].id}>{props.headings[1].title}</h2>
1111
JSON Web Tokenが役立つシナリオをいくつかご紹介します。
1212

1313
- **認証および認可**: JWTを使用する最も一般的な利用用途です。ユーザーがログインすると、その後の各リクエストにはJWTが含まれ、ユーザーはそのJWTで許可されたエンドポイント、リソースにアクセスできます。オーバーヘッドが小さく、異なるドメインのシステム間で簡単に使用できるため、シングルサインオンやSPAやモバイルアプリケーション、APIの呼び出しなどでJWTが使用されています。
1414
- **情報交換**: JSON Web Tokenは、システム間で認証や認可の情報を安全にやりとりする際に優れた形式です。JWTには署名できるため、例えば公開鍵/秘密鍵のペアを使用して、送信者が本人であることを確認できます。さらに、署名はヘッダーとペイロードを使って計算して作成されるため、コンテンツが改ざんされていないことも確認できます。
1515

16-
## JSON Web Tokenの構成は?
16+
<h2 id={props.headings[2].id}>{props.headings[2].title}</h2>
1717
JSON Web Tokenはコンパクトな形態で、ドット(.)で区切られた以下の3つの部分で構成されます。
1818

1919
- ヘッダー
@@ -93,7 +93,7 @@ JWTを操作してこれらの概念を実際に試したい場合は、<MdxAnch
9393

9494
<MarkdownImage src="https://cdn.auth0.com/website/jwt/introduction/debugger.png" alt="jwt.ioデバッガー" />
9595

96-
## JSON Web Tokenの仕組みとは?
96+
<h2 id={props.headings[3].id}>{props.headings[3].title}</h2>
9797
認証では、ユーザーが資格情報を使用して正常にログインすると、JSON Web Token (JWT)が返されます。トークンは資格情報であるため、セキュリティの問題が起きないように細心の注意を払う必要があります。一般的に、トークンは必要以上に長く保持するべきではありません。
9898

9999
保護されたエンドポイントにユーザーがアクセスしたい場合、ブラウザなどのクライアントはJWTを送信する必要があります。通常は、Bearerスキーマを使用してAuthorizationヘッダーで送信します。したがって、ヘッダーの内容は次のようになります。
@@ -116,7 +116,7 @@ JWTトークンをHTTPヘッダーで送信する場合は、トークンのサ
116116

117117
署名付きトークンの場合、トークンに含まれるすべての情報は、ユーザーやアクセスを許可をしているサードパーティーに公開されます。その情報が変更されることはありませんが、トークンの中にユーザやサードパーティに知られたくないような機密情報を入れないようにご注意して下さい。
118118

119-
## JSON Web Tokenを使用すべき理由とは?
119+
<h2 id={props.headings[4].id}>{props.headings[4].title}</h2>
120120

121121
**JSON Web Token (JWT)** の利点について、**Simple Web Token (SWT)** および XML を使用する **Security Assertion Markup Language Token (SAML)** と比較してみましょう。
122122

@@ -134,7 +134,7 @@ _エンコードされたJWTとエンコードされたSAMLの長さの比較_
134134

135135
JSON Web Tokenの詳細や、JSON Web Tokenを使用したアプリケーションの認証については、Auth0の<MdxAnchorComponent type="external" href="http://auth0.com/learn/json-web-tokens">JSON Web Tokenランディングページ</MdxAnchorComponent>をご覧ください。
136136

137-
## JWTのバリデーション(妥当性確認)とベリフィケーション(検証)の違い
137+
<h2 id={props.headings[5].id}>{props.headings[5].title}</h2>
138138

139139
JSON Web Token(JWT)のバリデーション(妥当性確認)とベリフィケーション(検証)はセキュリティ上非常に重要ですが、JWTセキュリティの異なる側面に対応しています。バリデーションはトークンが適切に構成され、強制可能なクレームを含んでいることを確認します。ベリフィケーションはトークンが真正で、変更されていないことを確認します。
140140

@@ -161,7 +161,7 @@ JSON Web Token(JWT)のバリデーション(妥当性確認)とベリフ
161161
多くのシステムでは、これらの手順は、包括的なセキュリティチェックにおける妥当性の確認と検証の両方を包含する「JWT検証」と呼ばれるものにまとめられることが多々ありますが、両者の区別は存在します。
162162

163163

164-
## JWTのデコーディングとエンコーディングの違い
164+
<h2 id={props.headings[6].id}>{props.headings[6].title}</h2>
165165

166166
JWTのエンコーディングでは、ヘッダーとペイロードをコンパクトでURLに適した形式に変換します。署名アルゴリズムとトークンタイプを記載するヘッダーと、サブジェクト、有効期限、発行時間などのクレームを含むペイロードの両方をJSONに変換しBase64URLエンコードします。これらのエンコードされた部分は、ドット(.)で連結され、その後、ヘッダーで指定されたアルゴリズムを使用して、シークレットキーまたはプライベートキーで署名が生成されます。この署名もBase64URLエンコードされ、送信や保存に適した形式でトークンを表す最終的なJWT文字列が生成されます。
167167

src/features/localization/dictionaries/introduction/en.ts

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,4 +44,36 @@ export const enIntroductionDictionary: IntroductionDictionaryModel = {
4444
description:
4545
"Learn about JSON Web Tokens, what are they, how they work, when and why you should use them.",
4646
},
47+
content: {
48+
headings: [
49+
{
50+
title: "What is JSON Web Token?",
51+
id: "what-is-json-web-token",
52+
},
53+
{
54+
title: "When should you use JSON Web Tokens?",
55+
id: "when-to-use-json-web-tokens",
56+
},
57+
{
58+
title: "What is the JSON Web Token structure?",
59+
id: "what-is-json-web-token-structure",
60+
},
61+
{
62+
title: "How do JSON Web Tokens work?",
63+
id: "how-json-web-tokens-work",
64+
},
65+
{
66+
title: "Why should we use JSON Web Tokens?",
67+
id: "why-use-json-web-tokens",
68+
},
69+
{
70+
title: "Difference Between Validating and Verifying a JWT",
71+
id: "difference-validating-verifying-jwt",
72+
},
73+
{
74+
title: "Difference Between Decoding and Encoding a JWT",
75+
id: "difference-decoding-encoding-jwt",
76+
},
77+
],
78+
},
4779
};

src/features/localization/dictionaries/introduction/ja.ts

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,4 +44,37 @@ export const jaIntroductionDictionary: IntroductionDictionaryModel = {
4444
description:
4545
"JSON Web Tokenとは何か、どのように機能するのか、いつ、なぜ使用する必要があるのかについて学びましょう。",
4646
},
47+
content: {
48+
headings: [
49+
{
50+
title: "JSON Web Tokenとは?",
51+
id: "what-is-json-web-token",
52+
},
53+
{
54+
title: "JSON Web Tokenはいつ使用すべきか?",
55+
id: "when-to-use-json-web-tokens",
56+
},
57+
{
58+
title: "JSON Web Tokenの構成は?",
59+
id: "what-is-json-web-token-structure",
60+
},
61+
{
62+
title: "JSON Web Tokenの仕組みとは?",
63+
id: "how-json-web-tokens-work",
64+
},
65+
{
66+
title: "JSON Web Tokenを使用すべき理由とは?",
67+
id: "why-use-json-web-tokens",
68+
},
69+
{
70+
title:
71+
"JWTのバリデーション(妥当性確認)とベリフィケーション(検証)の違い",
72+
id: "difference-validating-verifying-jwt",
73+
},
74+
{
75+
title: "JWTのデコーディングとエンコーディングの違い",
76+
id: "difference-decoding-encoding-jwt",
77+
},
78+
],
79+
},
4780
};

src/features/localization/models/introduction-dictionary.model.ts

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,4 +4,10 @@ import { HeroMetadataModel } from "@/features/common/models/hero-metadata.model"
44
export interface IntroductionDictionaryModel {
55
metadata: PageMetadataModel;
66
hero: HeroMetadataModel;
7+
content: {
8+
headings: {
9+
title: string,
10+
id: string
11+
}[]
12+
}
713
}

0 commit comments

Comments
 (0)