Last active
August 29, 2015 14:13
-
-
Save wblakecaldwell/f24a6ef7ab74c08bdec5 to your computer and use it in GitHub Desktop.
JSON Encoding in Go: Dealing with Sensitive Fields
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// | |
// Golang example: Handling sensitive struct fields when JSON encoding. | |
// | |
// Blog Post: http://blakecaldwell.net/blog/2015/1/20/json-encoding-in-go-dealing-with-sensitive-fields.html | |
// | |
// Try this in the Go Playground: https://play.golang.org/p/Du5ztx6zjC | |
// | |
// Author | |
// ------ | |
// | |
// Blake Caldwell | |
// http://blakecaldwell.net | |
// http://twitter.com/blakecaldwell | |
// | |
// Script Output | |
// ------------- | |
// | |
// Person: { | |
// "FirstName": "Arthur", | |
// "LastName": "Dent", | |
// "AuthToken": "green-ones" | |
// } | |
// SafePerson: { | |
// "FirstName": "Arthur", | |
// "LastName": "Dent" | |
// } | |
// PrettySafePerson - AuthToken has value: { | |
// "FirstName": "Arthur", | |
// "LastName": "Dent", | |
// "AuthToken": "green-ones" | |
// } | |
// PrettySafePerson - AuthToken is empty: { | |
// "FirstName": "Arthur", | |
// "LastName": "Dent" | |
// } | |
// PublicPerson: { | |
// "FirstName": "Arthur", | |
// "LastName": "Dent" | |
// } | |
// PublicPerson with AuthToken: { | |
// "FirstName": "Arthur", | |
// "LastName": "Dent", | |
// "AuthToken": "green-ones" | |
// } | |
// | |
package main | |
import ( | |
"encoding/json" | |
"fmt" | |
) | |
// Person struct that includes all fields in JSON | |
type Person struct { | |
FirstName string | |
LastName string | |
AuthToken string | |
} | |
// SafePerson omits AuthToken in JSON | |
type SafePerson struct { | |
FirstName string | |
LastName string | |
AuthToken string `json:"-"` | |
} | |
// PrettySafePerson omits AuthToken if it doesn't have a value | |
type PrettySafePerson struct { | |
FirstName string | |
LastName string | |
AuthToken string `json:",omitempty"` | |
} | |
// PublicPerson decorates a Person, hiding AuthToken by default | |
type PublicPerson struct { | |
*Person | |
AuthToken string `json:",omitempty"` | |
} | |
// IncludeAuthToken unhides the Person's AuthToken | |
func (p *PublicPerson) IncludeAuthToken() { | |
p.AuthToken = p.Person.AuthToken | |
} | |
func main() { | |
// Print JSON for a Person, which shows all fields | |
person := Person{ | |
FirstName: "Arthur", | |
LastName: "Dent", | |
AuthToken: "green-ones", | |
} | |
printJSON("Person", person) | |
// Print JSON for a SafePerson, which hides AuthToken because it's always omitted | |
safePerson := SafePerson{ | |
FirstName: "Arthur", | |
LastName: "Dent", | |
AuthToken: "green-ones", | |
} | |
printJSON("SafePerson", safePerson) | |
// Print JSON for PrettySafePerson, which hides AuthToken if it's empty | |
prettySafePerson := PrettySafePerson{ | |
FirstName: "Arthur", | |
LastName: "Dent", | |
AuthToken: "green-ones", | |
} | |
printJSON("PrettySafePerson - AuthToken has value", prettySafePerson) | |
prettySafePerson.AuthToken = "" | |
printJSON("PrettySafePerson - AuthToken is empty", prettySafePerson) | |
// Print JSON for PublicPerson, which decorates Person, hiding AuthToken by overriding it | |
pe := PublicPerson{ | |
Person: &person, | |
} | |
printJSON("PublicPerson", pe) | |
// Print JSON for the same PublicPerson after including AuthToken | |
pe.IncludeAuthToken() | |
printJSON("PublicPerson with AuthToken", pe) | |
} | |
func printJSON(name string, thing interface{}) { | |
jsonBytes, err := json.MarshalIndent(thing, "", " ") | |
if err != nil { | |
fmt.Printf("ERROR: %s\n", err) | |
return | |
} | |
fmt.Printf("%s: %s\n", name, string(jsonBytes)) | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment