<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
  <channel>
    <title>Jwt on David Lang</title>
    <link>https://www.davidlang.tech/tags/jwt/</link>
    <description>Recent content in Jwt on David Lang</description>
    <generator>Hugo</generator>
    <language>en</language>
    <lastBuildDate>Sat, 05 Sep 2020 00:00:00 +0000</lastBuildDate>
    <atom:link href="https://www.davidlang.tech/tags/jwt/index.xml" rel="self" type="application/rss+xml" />
    <item>
      <title>JWT Authentication: Securing Your REST API</title>
      <link>https://www.davidlang.tech/posts/jwt-authentication-securing-your-rest-api/</link>
      <pubDate>Sat, 05 Sep 2020 00:00:00 +0000</pubDate>
      <guid>https://www.davidlang.tech/posts/jwt-authentication-securing-your-rest-api/</guid>
      <description>&lt;p&gt;JSON Web Tokens (JWT) are a compact way to represent claims between parties. For stateless REST APIs and SPAs, JWT-based auth is a standard pattern-when implemented correctly.&lt;/p&gt;&#xA;&lt;h2 id=&#34;token-structure&#34;&gt;Token Structure&lt;/h2&gt;&#xA;&lt;p&gt;A JWT has three Base64-encoded parts: header, payload, and signature. The server signs the token with a secret (HS256) or private key (RS256). Clients send &lt;code&gt;Authorization: Bearer &amp;lt;token&amp;gt;&lt;/code&gt; on each request.&lt;/p&gt;&#xA;&lt;h2 id=&#34;issuing-tokens-in-nodejs&#34;&gt;Issuing Tokens in Node.js&lt;/h2&gt;&#xA;&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#93a1a1;background-color:#002b36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-javascript&#34; data-lang=&#34;javascript&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#268bd2&#34;&gt;const&lt;/span&gt; jwt &lt;span style=&#34;color:#719e07&#34;&gt;=&lt;/span&gt; require(&lt;span style=&#34;color:#2aa198&#34;&gt;&amp;#39;jsonwebtoken&amp;#39;&lt;/span&gt;);&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#268bd2&#34;&gt;function&lt;/span&gt; login(req, res) {&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#268bd2&#34;&gt;const&lt;/span&gt; user &lt;span style=&#34;color:#719e07&#34;&gt;=&lt;/span&gt; validateCredentials(req.body);&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#719e07&#34;&gt;if&lt;/span&gt; (&lt;span style=&#34;color:#719e07&#34;&gt;!&lt;/span&gt;user) &lt;span style=&#34;color:#719e07&#34;&gt;return&lt;/span&gt; res.status(&lt;span style=&#34;color:#2aa198&#34;&gt;401&lt;/span&gt;).json({ error&lt;span style=&#34;color:#719e07&#34;&gt;:&lt;/span&gt; &lt;span style=&#34;color:#2aa198&#34;&gt;&amp;#39;Invalid credentials&amp;#39;&lt;/span&gt; });&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#268bd2&#34;&gt;const&lt;/span&gt; token &lt;span style=&#34;color:#719e07&#34;&gt;=&lt;/span&gt; jwt.sign(&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    { sub&lt;span style=&#34;color:#719e07&#34;&gt;:&lt;/span&gt; user.id, role&lt;span style=&#34;color:#719e07&#34;&gt;:&lt;/span&gt; user.role },&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    process.env.JWT_SECRET,&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    { expiresIn&lt;span style=&#34;color:#719e07&#34;&gt;:&lt;/span&gt; &lt;span style=&#34;color:#2aa198&#34;&gt;&amp;#39;1h&amp;#39;&lt;/span&gt; }&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  );&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  res.json({ token });&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;}&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id=&#34;middleware-verification&#34;&gt;Middleware Verification&lt;/h2&gt;&#xA;&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#93a1a1;background-color:#002b36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-javascript&#34; data-lang=&#34;javascript&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#268bd2&#34;&gt;function&lt;/span&gt; authMiddleware(req, res, next) {&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#268bd2&#34;&gt;const&lt;/span&gt; header &lt;span style=&#34;color:#719e07&#34;&gt;=&lt;/span&gt; req.headers.authorization;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#719e07&#34;&gt;if&lt;/span&gt; (&lt;span style=&#34;color:#719e07&#34;&gt;!&lt;/span&gt;header&lt;span style=&#34;color:#719e07&#34;&gt;?&lt;/span&gt;.startsWith(&lt;span style=&#34;color:#2aa198&#34;&gt;&amp;#39;Bearer &amp;#39;&lt;/span&gt;)) &lt;span style=&#34;color:#719e07&#34;&gt;return&lt;/span&gt; res.sendStatus(&lt;span style=&#34;color:#2aa198&#34;&gt;401&lt;/span&gt;);&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#719e07&#34;&gt;try&lt;/span&gt; {&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    req.user &lt;span style=&#34;color:#719e07&#34;&gt;=&lt;/span&gt; jwt.verify(header.slice(&lt;span style=&#34;color:#2aa198&#34;&gt;7&lt;/span&gt;), process.env.JWT_SECRET);&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    next();&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  } &lt;span style=&#34;color:#719e07&#34;&gt;catch&lt;/span&gt; {&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    res.sendStatus(&lt;span style=&#34;color:#2aa198&#34;&gt;401&lt;/span&gt;);&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  }&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;}&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id=&#34;security-checklist&#34;&gt;Security Checklist&lt;/h2&gt;&#xA;&lt;p&gt;Keep secrets out of source control. Use short expiration and refresh tokens for long sessions. Never store sensitive data in the payload-it is readable. Prefer HTTPS everywhere.&lt;/p&gt;</description>
    </item>
  </channel>
</rss>
