About this article
This article was created using an automated generation workflow leveraging generative AI. Based on RFC 7519, current Microsoft identity platform documentation, and existing Daily-Code-Samples, we will observe the structure of a JWT without using real access tokens.
Verification Status: 📘 Official information confirmed, PowerShell execution unverified
With JWTs, "having readable parts" and "being a trusted token" are two different things. Without pasting an actual Microsoft Entra access token, if you create a completely dummy header.payload.signature and experience only the Base64URL decode, you will understand this difference.
Running it first
We do not use real tokens. We only create unsigned data for educational purposes.
function To-Base64Url([string]$Text) {
$bytes = [Text.Encoding]::UTF8.GetBytes($Text)
[Convert]::ToBase64String($bytes).TrimEnd('=').Replace('+','-').Replace('/','_')
}
$header = '{"alg":"none","typ":"JWT"}'
$payload = '{"sub":"demo-user","role":"reader"}'
$token = "$(To-Base64Url $header).$(To-Base64Url $payload)."
Write-Host '[DUMMY]'
Write-Host $token
Write-Host '[SUCCESS] 3つの部分を持つ教育用データを作成しました'
The standard for JWT is RFC 7519.
Check this
., dividing it results in three parts.
header.payload.signature
The tail end this time is empty.alg=none because it is educational unsigned data of , and it cannot be used for authentication purposes.。
flowchart LR
H[header JSON] --> E1[Base64URL]
P[payload JSON] --> E2[Base64URL]
E1 --> J[header.payload.signature]
E2 --> J
J --> D[decodeして内容を読む]
D --> N[署名検証とは別]
Try decoding
Base64URL handles characters and padding slightly differently than standard Base64. In the full sample, we pad the data before converting it back to UTF-8.
function From-Base64Url([string]$Text) {
$b64 = $Text.Replace('-','+').Replace('_','/')
switch ($b64.Length % 4) {
2 { $b64 += '==' }
3 { $b64 += '=' }
0 { }
default { throw 'Base64URLの長さが不正です' }
}
[Text.Encoding]::UTF8.GetString([Convert]::FromBase64String($b64))
}
$parts = $token.Split('.')
Write-Host "[RESULT] header = $(From-Base64Url $parts[0])"
Write-Host "[RESULT] payload = $(From-Base64Url $parts[1])"
Change one part
Change the role in the dummy payload from reader to writer. Both the token string and the decode result will change easily.
This is important.Being readable and modifiable is separate from having a valid signature. In signed JWTs, the recipient verifies the signature and other factors to determine reliability.
Caution regarding Microsoft access tokens
Microsoft advises treating access tokens as sensitive credentials. Furthermore, client applications should generally treat access tokens as opaque strings, and it is safer not to assume that tokens intended for Microsoft APIs are always JWTs that you should decode yourself.
Do not use real tokens as educational material by pasting them into online decoders.
For professional use
Do not output tokens to logs
Do not paste real tokens onto third-party sites
Do not refer to decoding as signature validation
Do not confuse JWT / JWS / JWE
Check the official specifications of the target API before depending on token contents
Dummy data is sufficient for observing the structure.
GitHub Sample
Official Information / Primary Sources
Summary
Being able to decode parts of a JWT does not imply encryption or signature verification. By trying "read → change one part" with complete dummy data, you can understand payload readability and token reliability separately.
