<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>Security on dwmkerr.com</title><link>https://dwmkerr.com/categories/security/</link><description>Recent content in Security on dwmkerr.com</description><generator>Hugo -- gohugo.io</generator><language>en-uk</language><managingEditor>Dave Kerr</managingEditor><copyright>Copright &amp;copy; Dave Kerr</copyright><lastBuildDate>Tue, 24 Mar 2015 14:45:02 +0000</lastBuildDate><atom:link href="https://dwmkerr.com/categories/security/index.xml" rel="self" type="application/rss+xml"/><item><title>Manipulating JSON Web Tokens (JWTs)</title><link>https://dwmkerr.com/modifying-a-jwt-in-a-node-application/</link><pubDate>Tue, 24 Mar 2015 14:45:02 +0000</pubDate><guid>https://dwmkerr.com/modifying-a-jwt-in-a-node-application/</guid><description>&lt;p&gt;I&amp;rsquo;ve been writing a couple of web services lately that use &lt;a href="https://auth0.com/"&gt;Auth0&lt;/a&gt; for identity management. It&amp;rsquo;s a great platform that makes working with different identity providers a breeze.&lt;/p&gt;
&lt;p&gt;One thing that I couldn&amp;rsquo;t work out how to do at first was to quickly build a new JWT&lt;sup&gt;&lt;a href="#fn1" id="ref1"&gt;1&lt;/a&gt;&lt;/sup&gt; from an existing token. I wanted to take my current token, add some more data to it and return it to the user. So here&amp;rsquo;s a &amp;lsquo;why&amp;rsquo; and &amp;lsquo;how&amp;rsquo;.&lt;/p&gt;
&lt;h2 id="why"&gt;Why?&lt;/h2&gt;
&lt;p&gt;Why would you want to do this? A use case would be when you want to associate your a session with some data. For example, imagine a library gateway which offers access to a whole bunch of University libraries. First we authenticate. Then we ask for all of the libraries in the system. Then we ask for authorisation to use a specific library. We could put the library name in the token and pass it for every call onwards.&lt;/p&gt;
&lt;p&gt;It might look like this:&lt;/p&gt;
&lt;h4 id="1-authenticate"&gt;1. Authenticate&lt;/h4&gt;
&lt;p&gt;First, we authenticate, perhaps with a username and password.&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;POST libraries.com/api/authenticate
{&amp;#34;usename&amp;#34;:&amp;#34;calculon&amp;#34;,&amp;#34;password&amp;#34;:&amp;#34;dramatic...pause&amp;#34;}
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Then we can return a JWT if all is well:&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;{&amp;#34;jwt&amp;#34;:&amp;#34;eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiJjYWxjdWxvbiJ9.VWkAafAMCxazY7uBlPTJoQwCBdUIy3T1d-C4TfxhAZQ&amp;#34;}
&lt;/code&gt;&lt;/pre&gt;&lt;h4 id="2-work-with-the-service"&gt;2. Work with the Service&lt;/h4&gt;
&lt;p&gt;We can put this JWT in an &lt;code&gt;Authorization&lt;/code&gt; header and start asking for protected resources:&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;GET libraries.com/api/libraries
Authorization: Bearer eyJhb...AZQ
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;giving us:&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;[
{&amp;#34;name&amp;#34;: &amp;#34;Mars University Libary&amp;#34;, &amp;#34;slug&amp;#34;:&amp;#34;mul&amp;#34;},
{&amp;#34;name&amp;#34;: &amp;#34;Coney Island State Library&amp;#34;, &amp;#34;slug&amp;#34;:&amp;#34;cis&amp;#34;}
]
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Two libraries we can choose from. Now I want to present this choice to a user, but once they&amp;rsquo;ve made their choice I don&amp;rsquo;t want to change the libary again. I want to work with only one library in a session.&lt;/p&gt;
&lt;h4 id="3-add-data-to-the-token"&gt;3. Add Data to the Token&lt;/h4&gt;
&lt;p&gt;A nice thing we can do here is just create &lt;em&gt;another&lt;/em&gt; authentication method, which attempts to see if we are authorised to use the given library:&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;POST libraries.com/api/libraries/mul/authorise
Authorization: Bearer eyJhb...AZQ
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;If the token is valid, we can check to see if the user is allowed to use this library. If so, we can return a &lt;em&gt;new&lt;/em&gt; token, which is associated with a &lt;em&gt;specific&lt;/em&gt; library:&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;HTTP/1.1 200 OK
{&amp;#34;jwt&amp;#34;: &amp;#34;eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiJjYWxjdWxvbiIsImxpYnJhcnkiOiJtdWwifQ.NM2pqRMkIp65u9unZnGIoyxK6v2A18730lPwSMrK93Q&amp;#34;}
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;This is a new token. Paste it into &lt;a href="https://jwt.io"&gt;jwt.io&lt;/a&gt;, you&amp;rsquo;ll see there&amp;rsquo;s a library code in the payload.&lt;/p&gt;
&lt;h4 id="4-work-with-the-service"&gt;4. Work with the service&lt;/h4&gt;
&lt;p&gt;Now I can call APIs like:&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;GET libaries.com/api/books
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;And my server can check the library in my token. If I have one, I return books from the given library, otherwise I return a 401.&lt;/p&gt;
&lt;h4 id="is-this-useful"&gt;Is this useful?&lt;/h4&gt;
&lt;p&gt;This specific example might not appeal, but you may well find as you write more complex services you want to at times add data to your token.&lt;/p&gt;
&lt;p&gt;The case above also shows how you can associate a session with a set of resources (in this case, a single library). This is useful if we know we&amp;rsquo;ll only work with a subset of resources. I want to choose a library once and work with that only. If you need to work with multiple libraries, it wouldn&amp;rsquo;t make sense.&lt;/p&gt;
&lt;h2 id="how"&gt;How?&lt;/h2&gt;
&lt;p&gt;If we are using Auth0, then we almost certainly have our token generated for us. The helper library &lt;a href="https://github.com/auth0/express-jwt"&gt;express-jwt&lt;/a&gt; will certainly let us make sure the token is valid, and put the payload of data on the &lt;code&gt;request.user&lt;/code&gt; object, but how can we create a new token &lt;em&gt;from the existing one&lt;/em&gt;?&lt;/p&gt;
&lt;p&gt;It turns out it&amp;rsquo;s really pretty easy, as we would expect as we are using open standards. Here&amp;rsquo;s the code:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-js" data-lang="js"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;var&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;jwt&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;require&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#39;jsonwebtoken&amp;#39;&lt;/span&gt;);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;function&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;extendToken&lt;/span&gt;(&lt;span style="color:#a6e22e"&gt;secret&lt;/span&gt;, &lt;span style="color:#a6e22e"&gt;payload&lt;/span&gt;, &lt;span style="color:#a6e22e"&gt;extend&lt;/span&gt;) {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#75715e"&gt;// Clone and extend the payload.
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;var&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;body&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;JSON&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;parse&lt;/span&gt;(&lt;span style="color:#a6e22e"&gt;JSON&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;stringify&lt;/span&gt;(&lt;span style="color:#a6e22e"&gt;payload&lt;/span&gt;));
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;for&lt;/span&gt; (&lt;span style="color:#66d9ef"&gt;var&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;prop&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;in&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;extend&lt;/span&gt;) {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;if&lt;/span&gt; (&lt;span style="color:#a6e22e"&gt;extend&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;hasOwnProperty&lt;/span&gt;(&lt;span style="color:#a6e22e"&gt;prop&lt;/span&gt;)) {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;body&lt;/span&gt;[&lt;span style="color:#a6e22e"&gt;prop&lt;/span&gt;] &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;extend&lt;/span&gt;[&lt;span style="color:#a6e22e"&gt;prop&lt;/span&gt;];
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; }
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; }
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#75715e"&gt;// Sign the new token with our secret.
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;return&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;jwt&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;sign&lt;/span&gt;(&lt;span style="color:#a6e22e"&gt;JSON&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;stringify&lt;/span&gt;(&lt;span style="color:#a6e22e"&gt;body&lt;/span&gt;), &lt;span style="color:#a6e22e"&gt;secret&lt;/span&gt;);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;We have a function which takes a secret, the payload of an existing token, an object containing data to extend and that&amp;rsquo;s it. Here&amp;rsquo;s how you could use it:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-js" data-lang="js"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;var&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;expressJwt&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;require&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#39;express-jwt&amp;#39;&lt;/span&gt;);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;var&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;mySecret&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;new&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;Buffer&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#39;walkinonsunshine&amp;#39;&lt;/span&gt;, &lt;span style="color:#e6db74"&gt;&amp;#39;base64&amp;#39;&lt;/span&gt;);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;// Middleware for protecting routes...
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;var&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;requireAuth&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;expressJwt&lt;/span&gt;({&lt;span style="color:#a6e22e"&gt;secret&lt;/span&gt;&lt;span style="color:#f92672"&gt;:&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;mySecret&lt;/span&gt;});
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#a6e22e"&gt;app&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;post&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#39;/api/libraries/:lib/authorise&amp;#39;&lt;/span&gt;, &lt;span style="color:#a6e22e"&gt;requireAuth&lt;/span&gt;, &lt;span style="color:#66d9ef"&gt;function&lt;/span&gt;(&lt;span style="color:#a6e22e"&gt;req&lt;/span&gt;, &lt;span style="color:#a6e22e"&gt;res&lt;/span&gt;, &lt;span style="color:#a6e22e"&gt;next&lt;/span&gt;) {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#75715e"&gt;// get the library, check the user has access...
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;var&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;lib&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;req&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;params&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;lib&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;checkLib&lt;/span&gt;(&lt;span style="color:#a6e22e"&gt;req&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;user&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;sub&lt;/span&gt;, &lt;span style="color:#a6e22e"&gt;lib&lt;/span&gt;, &lt;span style="color:#66d9ef"&gt;function&lt;/span&gt;(&lt;span style="color:#a6e22e"&gt;err&lt;/span&gt;, &lt;span style="color:#a6e22e"&gt;ok&lt;/span&gt;) {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;if&lt;/span&gt;(&lt;span style="color:#a6e22e"&gt;err&lt;/span&gt;) &lt;span style="color:#66d9ef"&gt;return&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;next&lt;/span&gt;(&lt;span style="color:#a6e22e"&gt;err&lt;/span&gt;);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;if&lt;/span&gt;(&lt;span style="color:#f92672"&gt;!&lt;/span&gt;&lt;span style="color:#a6e22e"&gt;ok&lt;/span&gt;) &lt;span style="color:#66d9ef"&gt;return&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;res&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;status&lt;/span&gt;(&lt;span style="color:#ae81ff"&gt;401&lt;/span&gt;).&lt;span style="color:#a6e22e"&gt;send&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#34;Access Denied.&amp;#34;&lt;/span&gt;);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;return&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;res&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;status&lt;/span&gt;(&lt;span style="color:#ae81ff"&gt;200&lt;/span&gt;).&lt;span style="color:#a6e22e"&gt;send&lt;/span&gt;({&lt;span style="color:#a6e22e"&gt;jwt&lt;/span&gt;&lt;span style="color:#f92672"&gt;:&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;extendToken&lt;/span&gt;(&lt;span style="color:#a6e22e"&gt;mySecret&lt;/span&gt;, &lt;span style="color:#a6e22e"&gt;req&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;user&lt;/span&gt;, {&lt;span style="color:#a6e22e"&gt;library&lt;/span&gt;&lt;span style="color:#f92672"&gt;:&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;lib&lt;/span&gt;})});
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; });
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;});
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;We&amp;rsquo;ve extended the original token with some new data, resigned it and passed it back to the user. Future requests will automatically have the &lt;code&gt;req.user.lib&lt;/code&gt; field set (as the entire token payload is put by default on the &lt;code&gt;req.user&lt;/code&gt; object with the express-js middleware.&lt;/p&gt;
&lt;p&gt;Hopefully that&amp;rsquo;ll be of some use if you ever need to extend the payload of a JWT token in a Node app.&lt;/p&gt;
&lt;hr&gt;
&lt;p&gt;&lt;sup id="fn1"&gt;1. Json Web Token, read more at &lt;a href="http://jwt.io/"&gt;jwt.io&lt;/a&gt;. &lt;a href="#ref1"&gt;↩&lt;/a&gt;&lt;/sup&gt;&lt;/p&gt;</description><category>CodeProject</category></item></channel></rss>