2017-09-26 6 views
2

あることからJSONのプロパティを省略するエレガントな方法私は、パスワードなどの機密フィールドを持つユーザー構造体を、持っている:golang - 直列化された

type User struct { 
    UID string `json:"uid" binding:"required"` 
    Password string `json:"password" binding:"required"` 
    EmailAddress string `json:"email" binding:"required"` 
} 

は今、私が登録し、この構造体を使用することができるようにしたいですユーザーと更新、削除、表示することもできます。私が望まないのは、パスワードをシリアライズして表示することです。私は、もちろん、カスタムマーシャルを作ることができますが、それは唯一の方法ですか?私はjson:"-"オプションを使ってみましたが、アンマーシャリング中に無視されてしまいました。私は望ましくありません。より良い方法がありますか?

EDIT: 使いやすさであなたたちのいくつかを置くために、私はもちろん、平文でパスワードを保存するつもりはありません。これは、パスワードのbcryptハッシュですが、それでもです。ユーザーを検索するときに返されることは望ましくありません。

+4

2つの構造体を使用できます.1つはpublic情報、もう1つはpublicを埋め込み、パスワードなどのプライベート情報を追加する完全版です。また、表示するときには、埋め込みpublic structのみを送信/シリアル化します。例については、関連する質問を参照してください:[構造体を別の構造体に割り当てる](https://stackoverflow.com/questions/31981592/assign-struct-with-another-struct/31981736#31981736)。 – icza

+2

ああ、これはおそらくあなたが "エレガント"に近づくことができるでしょう。特に異なるタグを使って同じ構造体を変換できるようになりました。私はそれを "custom marshaler"の下に表示しますが、JSONMarshalerの実装よりも簡単です。 – JimB

答えて

3

カスタムマーシャリングをしたい場合、私はjson.Marshalerを実装するエレガントなソリューションだと思います。それは、この場合には非常に簡単です:マーシャリングするときに、全くパスワードフィールドをしたくない場合は

func (u User) MarshalJSON() ([]byte, error) { 
    type user User // prevent recursion 
    x := user(u) 
    x.Password = "" 
    return json.Marshal(x) 
} 

は、あなたのユーザータイプで「omitempty」を追加します。

+0

あなたが正しいと思います。その周りに行くことはありません。私はいろいろな方法で試しましたが、優雅さの面ではこれだけです。 – ystark

3

簡単な解決策は、それをマーシャリングする前に、ユーザ構造体をサニタイズするために、次のようになります。

type User struct { 
    UID   string `json:"uid" binding:"required"` 
    Password  string `json:"password,omitempty" binding:"required"` 
    EmailAddress string `json:"email" binding:"required"` 
} 

func sanitizeUser(u User) User { 
    return User{u.UID, "", u.EmailAddress} 
} 

デモ:https://play.golang.org/p/RjKVoFc9o8

1

ここでは、この構造体を使用してユーザーを登録し、更新、削除、表示することができます。

もう1つの解決策は、構造体にパスワードをまったく格納しないことです。表示、削除、または更新する必要はありません(通常)。

ユーザレコードを作成する必要があります。その時点で、データストアにハッシュを保存します。

データストア内のハッシュを確認した時点で、ログイン時にIDを確認し、通常はサービスにアクセスするために使用できるトークンを発行する必要があります。

あなたが必要とするポイントがいくつかあります。そのポイントでは、単にメモリに保存してIDを確認するだけで、ほとんどの操作で構造体に公開する必要はありません。これは、エクスポートやロギングで誤って簡単に暴露される可能性がある構造体にIMOを置くよりも、より洗練されたIMOです。

+1

これは良い点です。 jsonドキュメントでパスワードを解析するには、単純に2回アンマーシャリングできます。パスワードフィールドを持たないユーザー構造体に入り、パスワードフィールドのみを持つ別の構造体に再度入れます。それが意味をなさないならば。 – Peter

3

私は別の構造体と構成に行きます。

パスワードをプレーンテキストで保存しないでください。パスワードは安全にハッシュされるべきです(bcrypt、pbkdf2など)。そのハッシュは格納されなければならず、決してシリアル化されるべきではありません。コンポジションを使用すると、次のようなことができます。

type User struct { 
    UID string `json:"uid" binding:"required"` 
    HashedPassword string `json:"-"` 
    EmailAddress string `json:"email" binding:"required"` 
} 

type UserFormData struct { 
    User 
    Password string `json:"password" binding:"required"` 
} 

これにより、柔軟性が向上します。

type UserFormData struct { 
    User 
    Password string `json:"password" binding:"required"` 
    ConfirmPassword string `json:"confirm_password" binding:"required"` 
} 

またあなたのユーザーオブジェクトの外にそのシリアライズの詳細を維持するという利点があります:あなたがパスワードを確認するようにユーザーに依頼した場合たとえば、あなたは、単にこのようなUserFormData構造体を変更することができます。

関連する問題