doumao9363 2014-04-03 11:13
浏览 1822
已采纳

序列化为JSON时,如何根据运行时条件忽略某些字段?

In a web service implemented in Go, I want to be able to restrict fields returned in a JSON response based on a user's role.

For example I may have a currently logged in user who has a role of guest and another with the role of admin

For an admin I want json to have all the keys eg

{
  id: 1,
  name: "John",
  role: "admin"
}

and for a guest to not have the role key eg

{
  id: 1,
  name: "John"
}

I can currently marshal the json and it returns all fields. I need to be able to restrict it.

  • 写回答

3条回答 默认 最新

  • dphdh395195 2014-04-03 11:43
    关注

    You can go by the suggestion @Volker made and clear struct fields for which the user has no permissions. This is probably the easiest to implement.

    A second option in a similar vein is to create a custom JSON encoder. One which encodes fields only if a role struct tag matches the current user's role. Here is some pseudo code to illustrate:

    type T struct {
        currentRole Role   `json:"-"`
        FieldA      string `json:"field_a,omitempty", role:"guest"`
        FieldB      string `json:"field_b,omitempty", role:"guest"`
        FieldC      int    `json:"field_c,omitempty", role:"admin"`
    }
    
    // Have T implement the encoding/json.Marshaler interface.
    func (t *T) MarshalJSON() ([]byte, error) {
        var buf bytes.Buffer
    
        // Use some reflection magic to iterate over struct fields.
        for _, field := range getStructFields(t) {
            // More reflection magic to extract field tag data.
            role := getFieldTag(field, "role")
    
            // If the field tag's role matches our current role,
            // we are good to go. otherwise, skip this field.
            if !matchingRole(role, t.currentRole) {
                continue // skip this field 
            }
    
            data, err := json.Marshal(fieldValue(field))
            ...
            _, err = buf.Write(data)
            ...
        }
    
        return buf.Bytes(), nil
    }
    

    This is going to be a pain to maintain if you need new roles though. So this would not be something I would lightly consider doing.

    Security concerns

    I am not entirely sure that what you are looking for is the right solution to your problem. This depends on the context in which you use your code, which is not clear from your question. But if this concerns a website where a user's abilities on the website are defined solely by the value of the role JSON field, then you are looking at a security hole. They can simply go into a browser debugger and change the value of this JSON object to include the "role: "admin" field. And presto! Instant administrative powers. Whether or not to render certain parts of a page, based on user role, should really be handled by the server, during template processing. Just like any and all data posted to the server should be checked and checked again to ensure it came from a trusted source.

    If none of this is applicable to you, then by all means, disregard this paragraph.

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论
查看更多回答(2条)

报告相同问题?

悬赏问题

  • ¥20 5037端口被adb自己占了
  • ¥15 python:excel数据写入多个对应word文档
  • ¥60 全一数分解素因子和素数循环节位数
  • ¥15 ffmpeg如何安装到虚拟环境
  • ¥188 寻找能做王者评分提取的
  • ¥15 matlab用simulink求解一个二阶微分方程,要求截图
  • ¥30 乘子法解约束最优化问题的matlab代码文件,最好有matlab代码文件
  • ¥15 写论文,需要数据支撑
  • ¥15 identifier of an instance of 类 was altered from xx to xx错误
  • ¥100 反编译微信小游戏求指导