<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en">
	<id>https://tech.uvoo.io/index.php?action=history&amp;feed=atom&amp;title=JWT</id>
	<title>JWT - Revision history</title>
	<link rel="self" type="application/atom+xml" href="https://tech.uvoo.io/index.php?action=history&amp;feed=atom&amp;title=JWT"/>
	<link rel="alternate" type="text/html" href="https://tech.uvoo.io/index.php?title=JWT&amp;action=history"/>
	<updated>2026-04-26T22:24:01Z</updated>
	<subtitle>Revision history for this page on the wiki</subtitle>
	<generator>MediaWiki 1.35.2</generator>
	<entry>
		<id>https://tech.uvoo.io/index.php?title=JWT&amp;diff=1376&amp;oldid=prev</id>
		<title>Busk at 16:12, 21 March 2021</title>
		<link rel="alternate" type="text/html" href="https://tech.uvoo.io/index.php?title=JWT&amp;diff=1376&amp;oldid=prev"/>
		<updated>2021-03-21T16:12:36Z</updated>

		<summary type="html">&lt;p&gt;&lt;/p&gt;
&lt;table class=&quot;diff diff-contentalign-left diff-editfont-monospace&quot; data-mw=&quot;interface&quot;&gt;
				&lt;col class=&quot;diff-marker&quot; /&gt;
				&lt;col class=&quot;diff-content&quot; /&gt;
				&lt;col class=&quot;diff-marker&quot; /&gt;
				&lt;col class=&quot;diff-content&quot; /&gt;
				&lt;tr class=&quot;diff-title&quot; lang=&quot;en&quot;&gt;
				&lt;td colspan=&quot;2&quot; style=&quot;background-color: #fff; color: #202122; text-align: center;&quot;&gt;← Older revision&lt;/td&gt;
				&lt;td colspan=&quot;2&quot; style=&quot;background-color: #fff; color: #202122; text-align: center;&quot;&gt;Revision as of 16:12, 21 March 2021&lt;/td&gt;
				&lt;/tr&gt;&lt;tr&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-lineno&quot; id=&quot;mw-diff-left-l156&quot; &gt;Line 156:&lt;/td&gt;
&lt;td colspan=&quot;2&quot; class=&quot;diff-lineno&quot;&gt;Line 156:&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class='diff-marker'&gt; &lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;     data = get_some_data_by_user_id(user_id)&lt;/div&gt;&lt;/td&gt;&lt;td class='diff-marker'&gt; &lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;     data = get_some_data_by_user_id(user_id)&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class='diff-marker'&gt; &lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;     return json.dumps(data)&lt;/div&gt;&lt;/td&gt;&lt;td class='diff-marker'&gt; &lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;     return json.dumps(data)&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td colspan=&quot;2&quot;&gt; &lt;/td&gt;&lt;td class='diff-marker'&gt;+&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&lt;ins style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;```&lt;/ins&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td colspan=&quot;2&quot;&gt; &lt;/td&gt;&lt;td class='diff-marker'&gt;+&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&lt;ins style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;&lt;/ins&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td colspan=&quot;2&quot;&gt; &lt;/td&gt;&lt;td class='diff-marker'&gt;+&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&lt;ins style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;&lt;/ins&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td colspan=&quot;2&quot;&gt; &lt;/td&gt;&lt;td class='diff-marker'&gt;+&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&lt;ins style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;```&lt;/ins&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td colspan=&quot;2&quot;&gt; &lt;/td&gt;&lt;td class='diff-marker'&gt;+&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&lt;ins style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;ssh-keygen -t rsa -b 4096 -m PEM -f jwtRS256.key&lt;/ins&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td colspan=&quot;2&quot;&gt; &lt;/td&gt;&lt;td class='diff-marker'&gt;+&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&lt;ins style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;# Don't use passphrase&lt;/ins&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td colspan=&quot;2&quot;&gt; &lt;/td&gt;&lt;td class='diff-marker'&gt;+&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&lt;ins style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;openssl rsa -in jwtRS256.key -pubout -outform PEM -out jwtRS256.key.pub&lt;/ins&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td colspan=&quot;2&quot;&gt; &lt;/td&gt;&lt;td class='diff-marker'&gt;+&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&lt;ins style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;cat jwtRS256.key&lt;/ins&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td colspan=&quot;2&quot;&gt; &lt;/td&gt;&lt;td class='diff-marker'&gt;+&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&lt;ins style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;cat jwtRS256.key.pub&lt;/ins&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class='diff-marker'&gt; &lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;```&lt;/div&gt;&lt;/td&gt;&lt;td class='diff-marker'&gt; &lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;```&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;/table&gt;</summary>
		<author><name>Busk</name></author>
	</entry>
	<entry>
		<id>https://tech.uvoo.io/index.php?title=JWT&amp;diff=203&amp;oldid=prev</id>
		<title>imported&gt;Jeremy-busk at 17:14, 29 May 2019</title>
		<link rel="alternate" type="text/html" href="https://tech.uvoo.io/index.php?title=JWT&amp;diff=203&amp;oldid=prev"/>
		<updated>2019-05-29T17:14:29Z</updated>

		<summary type="html">&lt;p&gt;&lt;/p&gt;
&lt;p&gt;&lt;b&gt;New page&lt;/b&gt;&lt;/p&gt;&lt;div&gt;# ECDSA SHA-512 pyjwt&lt;br /&gt;
&lt;br /&gt;
```&lt;br /&gt;
import jwt&lt;br /&gt;
&lt;br /&gt;
from cryptography.hazmat.primitives import serialization&lt;br /&gt;
&lt;br /&gt;
from cryptography.hazmat.backends import default_backend                                   &lt;br /&gt;
from cryptography.hazmat.primitives import hashes                                          &lt;br /&gt;
from cryptography.hazmat.primitives.asymmetric import ec    &lt;br /&gt;
                               &lt;br /&gt;
private_key = ec.generate_private_key(        &lt;br /&gt;
    ec.SECP384R1(), default_backend()&lt;br /&gt;
)   &lt;br /&gt;
data = b&amp;quot;this is some data I'd like to sign&amp;quot;&lt;br /&gt;
signature = private_key.sign(&lt;br /&gt;
    data,&lt;br /&gt;
    ec.ECDSA(hashes.SHA256())&lt;br /&gt;
)&lt;br /&gt;
 &lt;br /&gt;
&lt;br /&gt;
bytes_private_key = private_key.private_bytes(                                                  &lt;br /&gt;
    serialization.Encoding.PEM,                                                            &lt;br /&gt;
    serialization.PrivateFormat.PKCS8,                                                     &lt;br /&gt;
    serialization.NoEncryption())    &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
bytes_public_key = private_key.public_key().public_bytes(                                       &lt;br /&gt;
    serialization.Encoding.PEM,                                                           &lt;br /&gt;
    serialization.PublicFormat.SubjectPublicKeyInfo                                       &lt;br /&gt;
    )&lt;br /&gt;
&lt;br /&gt;
a = b'{private_key_data}'&lt;br /&gt;
b = b'{public_key_data}'          &lt;br /&gt;
&lt;br /&gt;
jwt_payload = {'iss': 'iss'}&lt;br /&gt;
ejwt = jwt.encode(jwt_payload, a, algorithm='ES512').decode('utf-8')&lt;br /&gt;
jwt.decode(ejwt, b, alogorithm='ES512')&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
View payload without verification&lt;br /&gt;
```&lt;br /&gt;
jwt.decode(jwt_token, verify=False)&lt;br /&gt;
jwt.get_unverified_header(jwt_token)&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
# Other&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
```&lt;br /&gt;
openssl ec -in ecprivkey.pem -pubout -out ecpubkey.pem&lt;br /&gt;
```&lt;br /&gt;
```&lt;br /&gt;
import jwt&lt;br /&gt;
# ssh-keygen -f ecdsa_key -e -m PKCS8 &amp;gt; ecdsa_key.pub&lt;br /&gt;
private_key = open('ecdsa_key', 'r').read()&lt;br /&gt;
public_key = open('ecdsa_key.pub', 'r').read()&lt;br /&gt;
&lt;br /&gt;
token = jwt.encode({ 'foo': 'bar' }, private_key, algorithm='ES256')&lt;br /&gt;
&lt;br /&gt;
print(jwt.decode(token, public_key, algorithms=['ES256']))&lt;br /&gt;
&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
# New&lt;br /&gt;
&lt;br /&gt;
https://blog.miguelgrinberg.com/post/json-web-tokens-with-public-key-signatures&lt;br /&gt;
&lt;br /&gt;
https://stackoverflow.com/questions/29650495/how-to-verify-a-jwt-using-python-pyjwt-with-public-key&lt;br /&gt;
&lt;br /&gt;
# Overview of Operation&lt;br /&gt;
&lt;br /&gt;
https://www.iana.org/assignments/jwt/jwt.xhtml#claims&lt;br /&gt;
&lt;br /&gt;
https://medium.com/vandium-software/5-easy-steps-to-understanding-json-web-tokens-jwt-1164c0adfcec&lt;br /&gt;
&lt;br /&gt;
https://developer.okta.com/blog/2018/06/20/what-happens-if-your-jwt-is-stolen&lt;br /&gt;
&lt;br /&gt;
https://medium.com/@darutk/understanding-id-token-5f83f50fa02e&lt;br /&gt;
&lt;br /&gt;
# RFC &amp;amp; Wiki &lt;br /&gt;
&lt;br /&gt;
https://tools.ietf.org/html/rfc7519&lt;br /&gt;
&lt;br /&gt;
https://en.wikipedia.org/wiki/JSON_Web_Token#Standard_fields&lt;br /&gt;
&lt;br /&gt;
https://www.pingidentity.com/content/ping/en/company/blog/posts/2019/jwt-security-nobody-talks-about.html&lt;br /&gt;
&lt;br /&gt;
# Usage&lt;br /&gt;
&lt;br /&gt;
https://blog.miguelgrinberg.com/post/json-web-tokens-with-public-key-signatures&lt;br /&gt;
&lt;br /&gt;
```&lt;br /&gt;
pip3 install pyjwt&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
```&lt;br /&gt;
JWT_SECRET = 'secret'&lt;br /&gt;
encoded_jwt = jwt.encode({'some': 'payload'}, 'secret', algorithm='HS512')&lt;br /&gt;
jwt.decode(encoded_jwt, 'secret') &lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
* https://jwt.io/&lt;br /&gt;
&lt;br /&gt;
# Refresh Tokens&lt;br /&gt;
* https://flask-jwt-extended.readthedocs.io/en/latest/refresh_tokens.html&lt;br /&gt;
* https://auth0.com/blog/refresh-tokens-what-are-they-and-when-to-use-them/&lt;br /&gt;
&lt;br /&gt;
# Resources&lt;br /&gt;
&lt;br /&gt;
* https://medium.com/vandium-software/5-easy-steps-to-understanding-json-web-tokens-jwt-1164c0adfcec&lt;br /&gt;
* https://developers.google.com/identity/toolkit/securetoken&lt;br /&gt;
* https://pyjwt.readthedocs.io/en/latest/usage.html&lt;br /&gt;
&lt;br /&gt;
# Storage&lt;br /&gt;
&lt;br /&gt;
Store as a Secure Cookie in browser and not in storage path&lt;br /&gt;
&lt;br /&gt;
* https://stormpath.com/blog/where-to-store-your-jwts-cookies-vs-html5-web-storage&lt;br /&gt;
&lt;br /&gt;
# Example&lt;br /&gt;
&lt;br /&gt;
From https://developers.google.com/identity/toolkit/securetoken&lt;br /&gt;
&lt;br /&gt;
```&lt;br /&gt;
{&lt;br /&gt;
  &amp;quot;iss&amp;quot;: &amp;quot;https://securetoken.google.com&amp;quot;,&lt;br /&gt;
  &amp;quot;sub&amp;quot;: &amp;quot;user_id&amp;quot;&lt;br /&gt;
  &amp;quot;aud&amp;quot;: &amp;quot;project_id&amp;quot;,&lt;br /&gt;
  &amp;quot;iat&amp;quot;: issued_at,&lt;br /&gt;
  &amp;quot;exp&amp;quot;: seconds_to_expiration,&lt;br /&gt;
  &amp;quot;email&amp;quot;: &amp;quot;user_email&amp;quot;&lt;br /&gt;
}&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
Using Flask and PyJWT:&lt;br /&gt;
```&lt;br /&gt;
@app.route(&amp;quot;/example_endpoint&amp;quot;)&lt;br /&gt;
def example_endpoint():&lt;br /&gt;
    access_token = flask.headers[&amp;quot;Authorization&amp;quot;]&lt;br /&gt;
    try:&lt;br /&gt;
        user_data = jwt.decode(access_token,&lt;br /&gt;
                               issuer=&amp;quot;https://securetoken.google.com&amp;quot;,&lt;br /&gt;
                               audience=&amp;quot;exemplary-example-123456&amp;quot;)&lt;br /&gt;
    except jwt.InvalidTokenError:&lt;br /&gt;
        return 401  # Invalid token&lt;br /&gt;
    except jwt.ExpiredSignatureError:&lt;br /&gt;
        return 401  # Token has expired&lt;br /&gt;
    except jwt.InvalidIssuerError:&lt;br /&gt;
        return 401  # Token is not issued by Google&lt;br /&gt;
    except jwt.InvalidAudienceError:&lt;br /&gt;
        return 401  # Token is not valid for this endpoint&lt;br /&gt;
    user_id = user_data[&amp;quot;sub&amp;quot;]&lt;br /&gt;
    data = get_some_data_by_user_id(user_id)&lt;br /&gt;
    return json.dumps(data)&lt;br /&gt;
```&lt;/div&gt;</summary>
		<author><name>imported&gt;Jeremy-busk</name></author>
	</entry>
</feed>