【问题标题】:What is the proper way to validate and sanitize JSON response from REST API?验证和清理来自 REST API 的 JSON 响应的正确方法是什么?
【发布时间】:2021-03-16 11:04:17
【问题描述】:

我已阅读有关此问题的 wordpress 页面,但没有找到解决方案。

这是我的详细信息:

注册休息路线:

        register_rest_route(
            '/jwt-auth/v1',
            '/user',
            array(
                'methods'             => array( 'GET', 'POST', 'PUT' ),
                'callback'            => array( $this, 'user_get_information' ),
                'permission_callback' => function() {
                    return is_user_logged_in();
                },
            ),
        );

用户功能:

public function user_get_information( $request ) {
    $user_id = get_current_user_id();
    $data    = array();
    if ( filter_input( INPUT_SERVER, 'REQUEST_METHOD' ) === 'POST' ) {
        $params = array(
            'nickname',
            'first_name',
            'last_name',
            'mobile',
            'favorites',
            'playtime',
        );

        $allreq = $request->get_params();

        foreach ( $allreq as $req => $val ) {
            if ( ! empty( $val ) && in_array( $req, $params, true ) ) {
                if ( 'favorites' === $req ) {
                    // do somthing
                } elseif ( 'playtime' === $req ) { 

// i want this json data validate and sanitize then add to database

                    $meta      = get_user_meta( $user_id, 'playtime', true );
                    $schema    = $this->user_playtime_meta_schema();
                    if ( rest_validate_value_from_schema( $val, $schema ) ) {
                        $sanitized = rest_sanitize_value_from_schema( $val, $schema );
                    }
                    if ( ! is_array( $meta ) ) {
                        $meta = array();
                    }
                    $meta[] = $sanitized;
                    // $meta = array();
                } else {
                    $meta = $val;
                }
                $user_meta = update_user_meta( $user_id, 'playtime', $meta );
            }
        }
    }
    if ( is_wp_error( $user_meta ) ) {
        $error_string = $user_meta->get_error_message();
        return $error_string;
    } else {
        $info   = get_user_by( 'ID', $user_id );
        $meta   = get_user_meta( $user_id );
        $img_id = $meta['image_select'][0];
        if ( $img_id ) {
            $img_url = wp_get_attachment_url( $img_id );
        }
        $data['id']           = $info->ID;
        $data['login']        = $info->user_login;
        $data['email']        = $info->user_email;
        $data['display_name'] = $info->display_name;
        $data['image']        = $img_url;
        $data['nickname']     = $meta['nickname'][0];
        $data['first_name']   = $meta['first_name'][0];
        $data['last_name']    = $meta['last_name'][0];
        $data['mobile']       = $meta['mobile'][0];
        $data['favorites']    = get_user_meta( $user_id, 'favorites', true );
        $data['playtime']     = get_user_meta( $user_id, 'playtime', true );
        return $data;
    }
}

架构:

public function user_playtime_meta_schema() {
    if ( $this->playtime_schema ) {
        return $this->playtime_schema;
    }
    $this->playtime_schema = array(
        'type' => array(
            'type'       => 'object',
            'properties' => array(
                'song'     => array(
                    'type'       => 'object',
                    'properties' => array(
                        'name'  => array(
                            'type' => 'string',
                        ),
                        'id'    => array(
                            'type' => 'number',
                        ),
                        'notes' => array(
                            'type' => 'number',
                        ),
                    ),
                ),
                'time'     => array(
                    'type' => 'string',
                ),
                'date'     => array(
                    'type' => 'string',
                ),
                'score'    => array(
                    'type' => 'string',
                ),
                'progress' => array(
                    'type' => 'string',
                ),
            ),
        ),
    );
    return $this->playtime_schema;
}

尝试像这样发送数据:

{"playtime":{"song": {
        "name": "Training New",
        "id": 758,
        "notes": 65
    },
    "time": "10:27:19 PM",
    "score": "[[76,\"perfect\"],[74,\"perfect\"],[77,\"perfect\"],[76,\"perfect\"],[74,\"late\"],[72,\"late\"],[74,\"perfect\"],[76,\"perfect\"],[76,\"perfect\"],[76,\"perfect\"],[74,\"perfect\"],[77,\"perfect\"],[76,\"late\"],[74,\"late\"],[72,\"perfect\"],[74,\"perfect\"],[76,\"perfect\"],[76,\"perfect\"],[74,\"perfect\"],[72,\"perfect\"],[71,\"perfect\"],[67,\"perfect\"],[74,\"perfect\"],[72,\"perfect\"],[74,\"perfect\"],[71,\"perfect\"],[72,\"perfect\"],[74,\"late\"],[71,\"perfect\"],[72,\"perfect\"],[71,\"late\"],[67,\"perfect\"]]",
    "date": "8/17/2020",
    "progress": "4%"}
}

一切正常,但如果我发送一些这样的不良信息:

    {"playtime":{"wrong": {
        "number": "1",
        "notes": 525
    },
    "time": "10:27:19 PM",
    "progress": "4%"}
}

同样有效,错误的数据会保存在数据库中!

任何帮助提前谢谢。

【问题讨论】:

  • 这不是架构的工作方式,因此您的问题可能会在某些访问者看来只是陈述事实 - 不是问题。
  • 哦,对不起,我修好了。
  • register_rest_route 直接接受schema 参数,您是否尝试过在其中使用它而不是在自己的循环中使用它?
  • @ChrisHaas 是的,我以前做过,但没有使用自定义 api。

标签: php json wordpress schema


【解决方案1】:

我检查了您的示例,您的架构和您使用的方式存在问题。

首先让我向您展示您示例的正确架构:

function testSchema() 
{
    return [
        'type' => 'object',
        'required' => [
            'playtime',
        ],
        'properties' => [
            'playtime' => [
                'type' => 'object',
                'required' => [
                    'song',
                    'time',
                    'score',
                    'date',
                    'progress',
                ],
                'properties' => [
                    'song' => [
                        'type' => 'object',
                        'required' => [
                            'name',
                            'id',
                            'notes',
                        ],
                        'properties' => [
                            'name' => [
                                'type' => 'string',
                            ],
                            'id' => [
                                'type' => 'integer',
                                'required' => true,
                            ],
                            'notes' => [
                                'type' => 'integer',
                            ],
                        ],
                    ],
                    'time' => [
                        'type' => 'string',
                    ],
                    'score' => [
                        'type' => 'string',
                    ],
                    'date' => [
                        'type' => 'string',
                    ],
                    'progress' => [
                        'type' => 'progress',
                    ],
                ],
            ],
        ],
    ];
}

要验证和清理您的输入,您的回调方法必须如下所示:

function testCallback(WP_REST_Request $request)
{
    $values = $request->get_json_params();
    $schema = testSchema();
    
    $result = rest_validate_value_from_schema($values, $schema);
    if (is_wp_error($result)) {
        var_dump($result);
        die('error');
    } else {
        $values = rest_sanitize_value_from_schema($values, $schema);
        var_dump($values);
        die('success');
    }
}

首先,您必须根据您的架构验证输入数据,如果输入通过它,那么您必须按照您在架构中描述的值来清理这些值 - 就是这样。

【讨论】:

  • 非常感谢先生,你让我过得愉快:)。我认为关键是$request->get_json_params();,而且你的架构工作得非常好。
  • 据我所知,这是获取 JSON 请求正文的正确方法 :)
猜你喜欢
  • 2016-09-12
  • 1970-01-01
  • 2016-01-26
  • 2018-08-23
  • 1970-01-01
  • 1970-01-01
  • 2019-01-19
  • 2017-03-05
  • 2018-02-23
相关资源
最近更新 更多