Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/json/14.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Php 如何避免在Symfony 3中通过JSON返回用户密码_Php_Json_Rest_Symfony - Fatal编程技术网

Php 如何避免在Symfony 3中通过JSON返回用户密码

Php 如何避免在Symfony 3中通过JSON返回用户密码,php,json,rest,symfony,Php,Json,Rest,Symfony,我正在开发一个集成了REST API的Symfony应用程序,但我面临一个问题,当通过API请求将用户实体返回为JSON时,它将返回用户密码,尽管已加密,但我希望避免使用它 我的用户实体是: <?php namespace AppBundle\Entity; use AppBundle\Util\Language; use Doctrine\ORM\Mapping as ORM; use Symfony\Component\Security\Core\User\AdvancedUser

我正在开发一个集成了REST API的Symfony应用程序,但我面临一个问题,当通过API请求将用户实体返回为JSON时,它将返回用户密码,尽管已加密,但我希望避免使用它

我的用户实体是:

<?php

namespace AppBundle\Entity;

use AppBundle\Util\Language;
use Doctrine\ORM\Mapping as ORM;
use Symfony\Component\Security\Core\User\AdvancedUserInterface;

/**
 * @ORM\Table(name="users")
 * @ORM\Entity(repositoryClass="AppBundle\Repository\UserRepository")
 */
class User implements AdvancedUserInterface, \Serializable
{
    public function __construct()
    {
        $this->isActive = true;
    }


    // Functions and parameters

    /**
     * Set password
     *
     * @param string $password
     *
     * @return User
     */
    public
    function setPassword($password)
    {
        $this->password = $password;
        return $this;
    }

    /**
     * Get password
     *
     *
     * @return string
     */
    public function getPassword()
    {
        return $this->password;
    }

    // More functions and parameters

    /** @see \Serializable::serialize() */
    public
    function serialize()
    {
        return serialize(array(
            $this->id,
            $this->username,
            $this->password,
            $this->isActive,
            $this->createdAt,
            $this->lastLogin,
        ));
    }

    /** @see \Serializable::unserialize() */
    public
    function unserialize($serialized)
    {
        list (
            $this->id,
            $this->username,
            $this->password,
            $this->isActive,
            $this->createdAt,
            $this->lastLogin,
            ) = unserialize($serialized);
    }
}
响应序列化程序

private static function serializeResponse($responseArray)
{
    $encoders = array(new JsonEncoder());
    $normalizers = array(new ObjectNormalizer());
    $serializer = new Serializer($normalizers, $encoders);
    return $serializer->serialize($responseArray, 'json');
}
还有一个API调用,它返回一个
用户
实体(还有更多)

这是来自上述方法的一个JSON响应

{
    "responseCode": "successfulResponseCode",
    "responseMsg": "Data received",
    "userLocale": "es",
    "workday": {
        "id": 10,
        ... so many data
        "job": {
            "id": 11,
            .. more json data
        },
        "user": {
            "username": "amendez",
            "password": "encrypted_password",
            ... more data
        },
        ... and more data
    }
}
正如您所看到的,我收到一个JSON对象,其中包含用户的加密密码和许多其他数据,我的目标是避免返回密码密钥和值


有人知道我如何实现它吗?

您需要使用指定的所需getter定义序列化程序组。请参阅:

首选(最佳实践)方法是分配所需的组

use Symfony\Component\Serializer\Annotation\Groups;

class User implements AdvancedUserInterface, \Serializable
{        
    /**
     * @Groups({"api"})
     * @return string
     */
    public function getUsername()
    {
        return $this->username;
    }


    //...    

    /**
     * Get password
     * @return string
     */
    public function getPassword()
    {
        return $this->password;
    }
}

为便于使用序列化程序服务而编辑

在您的
app/config/config.yml
中,启用注释,从而启用序列化程序服务

#config.yml
framework:
    #...
    serializer:
        enable_annotations: true
现在,您可以直接调用序列化程序服务或在自定义服务中使用DI

use Symfony\Component\Serializer\Encoder\JsonEncoder;
use Symfony\Component\HttpFoundation\JsonResponse;

private static function serializeResponse($responseArray)
{
     $serializer = $this->container->get('serializer');

     return $serializer->serialize($responseArray, JsonEncoder::FORMAT, array(
        'groups' => array('api'),
        'json_encode_options' => JsonResponse::DEFAULT_ENCODING_OPTIONS
    ));
}

手动将序列化程序组件与组一起使用

use Symfony\Component\Serializer\Mapping\Factory\ClassMetadataFactory;
use Doctrine\Common\Annotations\AnnotationReader;
use Symfony\Component\Serializer\Mapping\Loader\AnnotationLoader;

private static function serializeResponse($responseArray)
{
    $classMetadataFactory = new ClassMetadataFactory(new AnnotationLoader(new AnnotationReader()));

    $normalizer = new ObjectNormalizer($classMetadataFactory);
    $encoder = new JsonEncoder();
    $serializer = new Serializer(array($normalizer), array($encoder));

    return $serializer->serialize($responseArray, JsonEncoder::FORMAT, array('groups' => array('api')));
}

或者,您应该能够将其设置为被忽略属性的一部分。见:


您是否尝试过将密码从用户实体上的序列化函数和取消序列化函数中取出?是的,我尝试过但未成功OP需要在序列化方法中使用密码来保持与FOSUserBundle或默认防火墙实体提供程序的一致性@fyrye这是我没有尝试过的,我会这样做,并让你知道,非常感谢@fyrye我尝试了第二种方法,它很有效,所以我认为第一种方法也有效,因为它是相同的,但在另一方面。我会尝试,因为正如你所说,这是推荐的方法,如果我找到任何标志,我会让你知道。我真的很感谢你的帮助:)没问题。Symfony建议使用此选项的原因是,您对可用组上下文的声明位于中心位置。因此,维护、故障排除和验证更加容易。而不是像手动忽略的那样分散在控制器和服务中。比如说,当进行另一个API序列化调用时,忘记了密码应该被忽略。是的,我明白了,我更喜欢这样做,以便尽可能容易维护,所以我想我会将其更改为另一种方法。再次感谢您的帮助,非常感谢info@AlbertoMéndez I添加了一种更简单的方法,使用带有组注释的序列化程序。
#config.yml
framework:
    #...
    serializer:
        enable_annotations: true
use Symfony\Component\Serializer\Encoder\JsonEncoder;
use Symfony\Component\HttpFoundation\JsonResponse;

private static function serializeResponse($responseArray)
{
     $serializer = $this->container->get('serializer');

     return $serializer->serialize($responseArray, JsonEncoder::FORMAT, array(
        'groups' => array('api'),
        'json_encode_options' => JsonResponse::DEFAULT_ENCODING_OPTIONS
    ));
}
use Symfony\Component\Serializer\Mapping\Factory\ClassMetadataFactory;
use Doctrine\Common\Annotations\AnnotationReader;
use Symfony\Component\Serializer\Mapping\Loader\AnnotationLoader;

private static function serializeResponse($responseArray)
{
    $classMetadataFactory = new ClassMetadataFactory(new AnnotationLoader(new AnnotationReader()));

    $normalizer = new ObjectNormalizer($classMetadataFactory);
    $encoder = new JsonEncoder();
    $serializer = new Serializer(array($normalizer), array($encoder));

    return $serializer->serialize($responseArray, JsonEncoder::FORMAT, array('groups' => array('api')));
}
private static function serializeResponse($responseArray)
{
    $normalizer = new ObjectNormalizer();
    $normalizer->setIgnoredAttributes(array('password'));

    $encoder = new JsonEncoder();
    $serializer = new Serializer(array($normalizer), array($encoder));

    return $serializer->serialize($responseArray, JsonEncoder::FORMAT);
}