<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Charity Atieno</title>
    <description>The latest articles on DEV Community by Charity Atieno (@charity254).</description>
    <link>https://dev.to/charity254</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F3723930%2F17089a1e-26be-4a78-ae54-ad847f99cbe6.jpg</url>
      <title>DEV Community: Charity Atieno</title>
      <link>https://dev.to/charity254</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/charity254"/>
    <language>en</language>
    <item>
      <title>What Are JWT Tokens and How Do They Work? A Beginner-Friendly Guide</title>
      <dc:creator>Charity Atieno</dc:creator>
      <pubDate>Mon, 23 Mar 2026 07:16:12 +0000</pubDate>
      <link>https://dev.to/charity254/what-are-jwt-tokens-and-how-do-they-work-a-beginner-friendly-guide-32a4</link>
      <guid>https://dev.to/charity254/what-are-jwt-tokens-and-how-do-they-work-a-beginner-friendly-guide-32a4</guid>
      <description>&lt;p&gt;&lt;em&gt;Posted as part of my build-in-public series on Kaya, a verified house-hunting platform I am building for the Kenyan market.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fuc2x6l0gc46un7xos5lf.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fuc2x6l0gc46un7xos5lf.png" alt="JSON web tokens Authentication"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;If you have ever logged into a website and stayed logged in as you moved from page to page, something behind the scenes was keeping track of who you are. One of the most common ways modern backends handle this is with JWT tokens. When I started building the authentication system for Kaya, JWTs were one of the first things I had to truly understand, not just use from a tutorial, but actually get. This article is my attempt to explain them the way I wish someone had explained them to me.&lt;br&gt;
&lt;strong&gt;The Problem JWTs Solve&lt;/strong&gt;&lt;br&gt;
Before JWTs, the most common approach to authentication was sessions. Think of it like a coat check at a restaurant. You hand over your coat, the attendant gives you a ticket with a number on it, and every time you want your coat back you show the ticket and they look up your coat in the back room. Simple enough when there are ten people. But what happens when there are ten thousand? The back room gets crowded, the lookups get slower, and the whole system starts to strain.&lt;/p&gt;

&lt;p&gt;That is exactly what happens with session-based authentication at scale. You log in, the server creates a session record in a database, and sends you a session ID as a cookie. Every single request you make sends that session ID back, and the server has to look it up in the database every single time. As your application grows, this puts real pressure on your infrastructure.&lt;br&gt;
JWTs offer a completely different approach, one where the server does not need to store anything at all.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;So What Is a JWT?&lt;/strong&gt;&lt;br&gt;
JWT stands for JSON Web Token. Instead of the coat check giving you a ticket and keeping your coat in a back room, imagine they stamped all your details directly onto a card, sealed it with wax, and gave it back to you. Now whenever you show up, they just read the card and check the seal. No back room. No lookups. If the seal is intact, you are good.&lt;/p&gt;

&lt;p&gt;That is a JWT. It is a compact, self-contained string that carries the user's information and a cryptographic signature to prove it has not been tampered with. A JWT looks something like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight go"&gt;&lt;code&gt;&lt;span class="n"&gt;eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;eyJ1c2VyX2lkIjoiYWJjLTEyMyIsImV4cCI6MTcwMDAwMDAwMH0&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Looks like chaos, right? It is actually three parts separated by dots: the header, the payload, and the signature. Let us break each one down.&lt;br&gt;
&lt;strong&gt;Part One: The Header&lt;/strong&gt;&lt;br&gt;
The header is the least exciting part. It simply tells the server what type of token this is and which algorithm was used to sign it.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"alg"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"HS256"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"typ"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"JWT"&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;HS256 stands for HMAC with SHA-256, a secure and widely used signing algorithm. This object is then Base64URL encoded to produce the first chunk of the token. Nothing secret here, just metadata.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Part Two: The Payload&lt;/strong&gt;&lt;br&gt;
This is where the actual information lives. The payload contains what are called claims, which are just key-value pairs describing the user or the token itself.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"user_id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"abc-123"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"phone"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"254712345678"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"exp"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;1700000000&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Some common claims you will encounter are sub, which is the subject and usually holds the user's ID, exp which is the expiry timestamp telling the server when this token stops being valid, and iat which is the issued-at time recording when the token was created.&lt;/p&gt;

&lt;p&gt;Here is the part that trips a lot of beginners up: the payload is encoded, not encrypted. That means anyone who gets hold of a JWT can decode it and read everything inside. Go ahead and paste any JWT into jwt.io and you will see exactly what I mean. So the golden rule is this: never put sensitive information like passwords or secret keys inside a JWT payload.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Part Three: The Signature&lt;/strong&gt;&lt;br&gt;
This is where the trust lives. The signature is created by taking the encoded header and payload, combining them, and running them through a hashing algorithm using a secret key that only your server knows.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;HMACSHA256(
  base64UrlEncode(header) + "." + base64UrlEncode(payload),
  your-secret-key
)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Think of the signature as the wax seal on that card from our earlier analogy. When someone presents a token, your server re-runs this calculation using its secret key. If the signature matches, the token is genuine. If someone has tampered with the payload, even by changing one single character, the signature will not match and the server will reject the token immediately.&lt;/p&gt;

&lt;p&gt;This is the elegant part of JWTs: the server can verify who you are without asking anyone or looking anything up. The token proves itself.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;How the Full Flow Works&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Let us walk through what actually happens when a user logs in to an app that uses JWTs.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;User sends credentials to the server
         |
Server verifies the credentials
         |
Server creates a JWT with the user's ID and expiry,
signs it with the secret key, and sends it back
         |
User stores the token (in memory or localStorage)
         |
For every future request, the user sends:
Authorization: Bearer &lt;span class="nt"&gt;&amp;lt;token&amp;gt;&lt;/span&gt;
         |
Server reads the token, verifies the signature,
checks the expiry, knows who you are.
No database. No session lookup. Done.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You will notice the word Bearer before the token. It is just a convention that tells the server what kind of credential is being sent. It means "the person presenting this token should be granted access." Nothing more to it than that.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Why Tokens Cannot Live Forever&lt;/strong&gt;&lt;br&gt;
Every JWT should have an expiry time. In the Kaya backend I set it to 24 hours. Here is why this matters: unlike sessions, a JWT cannot be invalidated by the server once it has been issued. If someone gets hold of your token, they can use it freely until it expires. Setting a short expiry limits the damage window if a token is ever compromised.&lt;/p&gt;

&lt;p&gt;This leads to one of the core trade-offs of JWTs. They are fast, stateless, and scale beautifully because the server stores nothing. But they are also difficult to revoke. If you need to log a user out immediately, for example if their account is suspended, you have to build additional mechanisms on top of the basic JWT approach to handle that. For most applications though, a sensible expiry time is enough.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;How This Fits Into Kaya&lt;/strong&gt;&lt;br&gt;
In the Kaya backend, JWTs sit at the heart of the authentication system. When a user successfully verifies their identity, the server creates a JWT containing their unique ID, signs it with a secret key stored securely in the environment, and returns it to the client. From that point on, every request to a protected route must include that token. A middleware function intercepts each request, validates the token, and either allows it through or returns a 401 Unauthorized response.&lt;br&gt;
The result is a backend that never stores login state. Every request is self-contained and verified on the spot. For a platform like Kaya where access to certain listing details is gated behind verified identity and payment, having a reliable and stateless authentication layer is not optional; it is foundational.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Key Takeaways&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;A JWT is made of three parts: the header, the payload, and the signature&lt;/li&gt;
&lt;li&gt;The signature is what makes it trustworthy and proves nothing has been tampered with&lt;/li&gt;
&lt;li&gt;The payload is readable by anyone, so sensitive data should never go inside it&lt;/li&gt;
&lt;li&gt;Tokens should always have an expiry time to limit damage if one is ever compromised&lt;/li&gt;
&lt;li&gt;The server verifies everything using a secret key with no database lookup required&lt;/li&gt;
&lt;li&gt;JWTs are stateless, fast, and scale well but they cannot be invalidated once issued without additional mechanisms&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>jwt</category>
      <category>backenddevelopment</category>
      <category>go</category>
      <category>authentication</category>
    </item>
    <item>
      <title>Growing as a developer through open source contribution</title>
      <dc:creator>Charity Atieno</dc:creator>
      <pubDate>Tue, 24 Feb 2026 12:21:23 +0000</pubDate>
      <link>https://dev.to/charity254/growing-as-a-developer-through-open-source-contribution-35hi</link>
      <guid>https://dev.to/charity254/growing-as-a-developer-through-open-source-contribution-35hi</guid>
      <description>&lt;p&gt;Open source contribution is often described as a milestone in a developer’s journey. After recently contributing to a Go open source project, I now understand why.&lt;/p&gt;

&lt;p&gt;It is one thing to build personal projects where you control the structure, naming, and decisions. It is another thing entirely to step into a living codebase maintained by people across different time zones, skill levels, and perspectives. Open source forces you to grow in ways tutorials cannot.&lt;/p&gt;

&lt;p&gt;Many of us use open source tools daily. Frameworks, libraries, and developer tools quietly power our applications. Contributing shifts your mindset from being just a user to becoming a collaborator. Instead of asking how to use a tool, you begin asking how it works internally and how to improve it without disrupting existing behavior. That shift deepens your technical understanding significantly.&lt;/p&gt;

&lt;p&gt;One of the biggest lessons for me was learning to read and understand someone else’s code at scale. In open source, you cannot refactor everything to match your personal style. You must understand the existing architecture, follow established conventions, respect maintainers’ decisions, and ensure your changes align with the project’s direction. This builds discipline and strengthens your ability to work within constraints, just like in professional engineering teams.&lt;/p&gt;

&lt;p&gt;Open source is not just about writing code. It is about communication. You discuss ideas through issues, submit changes through pull requests, receive feedback, and revise your work when necessary. The focus is not on proving yourself right. The focus is on improving the project. This process builds humility, resilience, and clarity in how you explain technical decisions.&lt;/p&gt;

&lt;p&gt;Contributing also changes how you think about quality. You become more intentional about writing clean and readable code, considering edge cases, maintaining compatibility, and ensuring proper testing. In personal projects, speed often comes first. In open source, responsibility comes first because other developers rely on the code you contribute.&lt;/p&gt;

&lt;p&gt;For me, contributing to a Go open source project strengthened both my technical foundation and my confidence. It reminded me that real growth happens when you step into unfamiliar spaces and build in public.&lt;/p&gt;

</description>
      <category>opensource</category>
      <category>go</category>
      <category>learning</category>
      <category>devops</category>
    </item>
    <item>
      <title>Understanding APIs Through Errors JSON and Status Codes</title>
      <dc:creator>Charity Atieno</dc:creator>
      <pubDate>Fri, 13 Feb 2026 10:16:24 +0000</pubDate>
      <link>https://dev.to/charity254/understanding-apis-through-errors-json-and-status-codes-4441</link>
      <guid>https://dev.to/charity254/understanding-apis-through-errors-json-and-status-codes-4441</guid>
      <description>&lt;p&gt;I used to joke that APIs are like introverts at a party: you never know if they’ll respond or ignore you entirely. When I first started learning about them, I felt exactly like that completely in the dark.&lt;/p&gt;

&lt;p&gt;Over time, I’ve gradually improved. I’ve learned how GET and POST requests work, how to handle errors in JSON, and why sending the correct HTTP status codes matters. These may seem small, but they make your API predictable, professional, and friendly for anyone consuming it.&lt;/p&gt;

&lt;p&gt;Here are a few key lessons I’ve learned:&lt;/p&gt;

&lt;p&gt;GET vs POST: GET retrieves data, POST sends data. Using them correctly is the foundation of any API.&lt;/p&gt;

&lt;p&gt;Error Handling: Clear error messages in JSON help clients understand what went wrong and how to fix it.&lt;/p&gt;

&lt;p&gt;Status Codes Matter: Using the right HTTP status code communicates the result of a request without needing to dig into the response body. Examples:&lt;/p&gt;

&lt;p&gt;200 OK – request succeeded&lt;/p&gt;

&lt;p&gt;400 Bad Request – client sent invalid data&lt;/p&gt;

&lt;p&gt;401 Unauthorized – authentication required or failed&lt;/p&gt;

&lt;p&gt;Here’s a small Go example I built that takes a user’s name and returns a personalized greeting:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;
package main

import (
    "encoding/json"
    "net/http"
)

type User struct {
    Name string `json:"name"`
}

func greetHandler(w http.ResponseWriter, r *http.Request) {
    if r.Method != http.MethodPost {
        w.WriteHeader(http.StatusMethodNotAllowed)
        return
    }

    var user User
    decoder := json.NewDecoder(r.Body)
    if err := decoder.Decode(&amp;amp;user); err != nil {
        w.WriteHeader(http.StatusBadRequest)
        json.NewEncoder(w).Encode(map[string]string{"error": "Invalid JSON"})
        return
    }

    w.WriteHeader(http.StatusOK)
    json.NewEncoder(w).Encode(map[string]string{"message": "Hello " + user.Name})
}

func main() {
    http.HandleFunc("/greet", greetHandler)
    http.ListenAndServe(":8080", nil)
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Testing the API&lt;/p&gt;

&lt;p&gt;Once the server is running, you can test it easily:&lt;/p&gt;

&lt;p&gt;Using curl:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;curl -X POST http://localhost:8080/greet \
-H "Content-Type: application/json" \
-d '{"name":"Charity"}'
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You should see:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;{"message":"Hello Charity"}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Using Postman:&lt;/p&gt;

&lt;p&gt;Open Postman and create a new POST request.&lt;/p&gt;

&lt;p&gt;Set the URL to &lt;a href="http://localhost:8080/greet" rel="noopener noreferrer"&gt;http://localhost:8080/greet&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;In the body, select raw JSON and enter:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;{"name":"Charity"}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Send the request and you’ll see the greeting returned.&lt;/p&gt;

&lt;p&gt;Even this simple example reinforces why proper JSON formatting, error handling, and status codes are essential. Small improvements like these make APIs much easier to use and understand, and they transform something that once seemed intimidating into a tool I can confidently build with.&lt;/p&gt;

&lt;p&gt;APIs may have seemed introverted at first, but once you speak their language, they’re actually pretty friendly.&lt;/p&gt;

</description>
      <category>go</category>
      <category>api</category>
      <category>json</category>
      <category>statuscodes</category>
    </item>
  </channel>
</rss>
