Golang Tutorial: How to Implement JWT Authentication with Golang

Golang JWT Tutorial

Accessing an e-mail account anywhere in the world on any device requires authenticating yourself to prove the data associated with the account (e.g., e-mail address and inbox messages) belongs to you. Often, you must fill out a login form with credentials, such as an e-mail address and password, that uniquely identify your account. When creating an account, you provide this information in a sign-up form. Sometimes, the service sends either a confirmation e-mail or an SMS message to ensure that you own the supplied e-mail address or phone number.

Because it is highly likely that only you know the credentials to your account, authentication prevents unwanted actors from accessing your account and its data. Each time you log into your e-mail account and read your most recent unread messages, you, and like many other end users, don’t think about how the service implements authentication to protect/secure your data and hide your activity history. You’re busy and only want to spend a few minutes in your e-mail inbox before closing it out and resuming your day. For developers, the difficulty in implementing authentication comes from striking a balance between the user experience and the strength of the authentication. For example, a signup form may prompt the user to enter a password that contains not only alphanumeric characters but also must meet other requirements such as a minimum password length and punctuation marks. Asking for a stronger password decreases the likelihood of a malicious user correctly guessing it, but simultaneously, this password is increasingly more difficult for the user to remember. Keep in mind that poorly designed authentication can easily be bypassed and introduce more vulnerabilities into your application.

In most cases, applications implement session-based or token-based authentication to reliably verify a user’s identity and persist authentication for subsequent page visits. Since Golang is a popular choice for building server-side applications, Go’s ecosystem offers many third-party packages for implementing these solutions into your applications.

Having this knowledge is excellent to find Golang Jobs

Below, I’m going to show you how to integrate JWT authentication within a Go and chi application with the chi jwtauth middleware.

Session-Based Authentication vs. Token-Based Authentication#

Session-Based Authentication

Let’s imagine the following scenario. Within your e-mail inbox, you are asked to re-enter your e-mail address and password on every single action you take (e.g., opening an unread e-mail or switching to a different inbox tab) to verify your identity continuously. This implementation could be useful in the context of accidentally leaving your e-mail inbox open on a publicly-shared library computer when you have to step out to take a phone call. However, if the login credentials are sent over a non-HTTPS connection, then the login credentials are susceptible to a MITM (man-in-the-middle) attack and can be hijacked. Plus, it would result in a frustrating user experience and immediately drive users away to a different service. Traditionally, to persist authentication, an application establishes a session and saves an http-only cookie with this session’s ID inside the user’s browser. Usually, this session ID maps to the user’s ID, which can then be used to fetch the user’s information. Suppose you have ever built an Express.js application with the authentication middleware library Passport and session middleware library express-session. In that case, you are probably familiar with the connect.sid http-only cookie, a session ID cookie, and managing sessions with Redis.

const passport = require(“passport”); const session = require(“express-session”); const RedisStore = require(“connect-redis”)(session); // … const redis = require(“redis”).createClient({ url: “redis://xxxxxxxx:[email protected]:11339/” }); redis.on(“error”, console.error); // … app.use(session({ secret: “session secret”, store: new RedisStore({ client: redis }) })); app.use(passport.initialize()); app.use(passport.session()); // …

Browser - Session ID Cookie

In Redis, the connect.sid cookie’s corresponding key is the session ID (the substring proceeding s%3A and preceding the first dot of this cookie’s value) prefixed with sess:, and its value contains information about the cookie and user authenticated by Passport.

Redis - Session Key/Value

When a user sends an authentication request (via the standard username/password combination or an OAuth 2.0 provider such as Google/Facebook/Twitter), Passport determines which of these authentication mechanisms (“strategies”) to use to process the request.