JSON Encoding in Go: Dealing with Sensitive Fields

JSON marshalling in Go is pretty straight-forward, but sometimes your structs contain sensitive information that you'd like to keep out of your public JSON API. Fortunately, there are a few good solutions that don't require you to manually copy every field from one struct type to another.

Let's start with our basic Person struct:

The simplest way to prevent exposing AuthToken via JSON is with the `json:"-"` key, which tells the JSON package to always ignore this field. Let's call this "SafePerson", because you never have to worry about exposing AuthToken via JSON:

This works really well, until you need to include the field some of the time, like when showing someone their own record. In that case, you could try the `json:",omitempty"` key, which only includes the field if it has a value. It'd be up to you to clear it out when it doesn't belong in the JSON. This is "PrettySafePerson", because it's safe if you're careful:

This is great, but... here's the thing. That one time you forget to clear an AuthToken for someone other than the Person that it represents might give you quite the headache. I'd rather err on the side of safety, where forgetting something means not showing data that I meant to. 

Here's where we can take advantage of Go's type embedding. By embedding a Person inside another struct, we borrow all of the Person's fields, and can override some without affecting the Person. We'll build our API with this pattern, which always omit sensitive fields unless told otherwise:

PublicPerson's AuthToken field overrides the embedded Person.AuthToken, and because of the `json:",omitempty"` key, it'll be hidden from JSON unless you set it. Person.AuthToken still has the original value, you can include it in the JSON by calling IncludeAuthToken().

Try it out in the Go Playground

View Source on Github

PrintView Printer Friendly Version

EmailEmail Article to Friend

References (12)

References allow you to track sources for this article, as well as articles that were written in response to this article.

Reader Comments (3)

Thank's for posting this! Very useful.

January 21, 2015 | Unregistered CommenterKeith Ball

This is a rather simple, yet novel approach to a not so uncommon of a problem. Thank you for this!

January 22, 2015 | Unregistered CommenterSam Zaydel

great post, very useful, it answers the problem that bothers me for a long time! thank you.

February 3, 2015 | Unregistered Commenterc4pt0r

PostPost a New Comment

Enter your information below to add a new comment.

My response is on my own website »
Author Email (optional):
Author URL (optional):
Some HTML allowed: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <code> <em> <i> <strike> <strong>
« Introduction to Docker: Tech Talk and Demo | Main | Solving a 2014 Google I/O Secret Invite Puzzle »