简体   繁体   中英

How to exclude password field from the user entity with JMS serializer using FOS User Bundle and Symfony 4?

I have implemented simple API with login functionality using FOSUserBundle and JWT (using LexikJWTAuthenticationBundle). All works well and I can login and get a jwt token. But when I created API endpoint to get user details the password field is sent in the response as well.

My controller method for fetching user details looks like this:

/**
 * @Route("/get/{id}", name="api_auth_get_user_by_id",  methods={"GET"})
 *
 * @param Request              $request
 * @param UserManagerInterface $userManager
 *
 * @return JsonResponse|\Symfony\Component\HttpFoundation\RedirectResponse
 */
public function getById(SystemUser $user)
{
    return $this->handleView($this->view($user));
}

My user entity looks like this:

<?php

namespace App\Entity\Api\Auth;

use Doctrine\ORM\Mapping as ORM;
use FOS\UserBundle\Model\User as BaseUser;

/**
 * @ORM\Entity
 * @ORM\Table(name="fos_user")
 */
class SystemUser extends BaseUser
{
    /**
     * @ORM\Id
     * @ORM\Column(type="integer")
     * @ORM\GeneratedValue(strategy="AUTO")
     */
    protected $id;

    public function __construct()
    {
        parent::__construct();
        // your own logic
    }
}

So as you can see my SystemUser entity extends from BaseUser entity which is found in FOSUserBundle .

This is how response JSON looks like when I get the user details from the API:

{
    "id": 1,
    "username": "test",
    "username_canonical": "test",
    "email": "test.user@super.com",
    "email_canonical": "test.user@super.com",
    "enabled": true,
    "password": "$2y$13$DnyFxYyJXQe3Z7chsJYwe.LUsuOWPqBtFm5.O0vwldX5AoMGld9ca",
    "last_login": "2019-08-27T06:19:43-04:00",
    "groups": [],
    "roles": []
}

So how can I exclude password property from the response. I am using latest Symfony 4.3. I know that in earlier versions of Symfony you could create a jms serializer config for each entity in your bundle but so much changed in Symfony 4 and now using bundles is not necessary and I am not using bundle for this simple app.

Correct way to exclude password property from entity that extends FOS User Bundle User entity is to configure packages/jms_serializer.yaml configuration like this:

jms_serializer:
    metadata:
        auto_detection: true
        directories:
            FOSUB:
                namespace_prefix: 'FOS\UserBundle'
                path: '%kernel.root_dir%/serializer' 

Also note that namespace_prefix must use single \\ as this will NOT WORK:

namespace_prefix: 'FOS\\UserBundle'

Second step is to create JMS serialization file for FOS User entity specifically like this:

FOS\UserBundle\Model\User:
    exclusion_policy: ALL
    properties:
        id:
            expose: true
        username:
            expose: true
        password:
            expose: false
        email:
            expose: true
        last_login:
            expose: true
        enabled:
            expose: true

which can be saved in src/serializer/Model.User.yml

One thing that was confusing me is that you can not configure serialization properties for parent class in configuration file for child class.

For example if you are to extend FOS\\UserBundle\\Model\\User entity with another entity SystemUser and you create serialization configuration file for that new entity in src/serialization/Entity.SystemUser.yml. From that Entity.SystemUser.yml file you CAN NOT exclude or configure any properties that are part of
FOS\\UserBundle\\Model\\User entity. For each parent class entity you must create its own serialization config file.

Also don't forget to clear the cache after you changing serialization config.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM