> APIs >

Course Overview

Login to bookmark this course

API Platform 3 Part 2: Security for your Treasures

Become a master in API security by creating dynamic fields, voters, and setting object owners automatically with our tutorial.

  • 2090 students
  • EN/ES Captions
  • EN/ES Script
  • Certificate of Completion

Your Guides

About this course

What PHP libraries does this tutorial use?

// composer.json
{
    "require": {
        "php": ">=8.1",
        "ext-ctype": "*",
        "ext-iconv": "*",
        "api-platform/core": "^3.0", // v3.1.2
        "doctrine/annotations": "^2.0", // 2.0.1
        "doctrine/doctrine-bundle": "^2.8", // 2.8.3
        "doctrine/doctrine-migrations-bundle": "^3.2", // 3.2.2
        "doctrine/orm": "^2.14", // 2.14.1
        "nelmio/cors-bundle": "^2.2", // 2.2.0
        "nesbot/carbon": "^2.64", // 2.66.0
        "phpdocumentor/reflection-docblock": "^5.3", // 5.3.0
        "phpstan/phpdoc-parser": "^1.15", // 1.16.1
        "symfony/asset": "6.2.*", // v6.2.5
        "symfony/console": "6.2.*", // v6.2.5
        "symfony/dotenv": "6.2.*", // v6.2.5
        "symfony/expression-language": "6.2.*", // v6.2.5
        "symfony/flex": "^2", // v2.2.4
        "symfony/framework-bundle": "6.2.*", // v6.2.5
        "symfony/property-access": "6.2.*", // v6.2.5
        "symfony/property-info": "6.2.*", // v6.2.5
        "symfony/runtime": "6.2.*", // v6.2.5
        "symfony/security-bundle": "6.2.*", // v6.2.6
        "symfony/serializer": "6.2.*", // v6.2.5
        "symfony/twig-bundle": "6.2.*", // v6.2.5
        "symfony/ux-react": "^2.6", // v2.7.1
        "symfony/ux-vue": "^2.7", // v2.7.1
        "symfony/validator": "6.2.*", // v6.2.5
        "symfony/webpack-encore-bundle": "^1.16", // v1.16.1
        "symfony/yaml": "6.2.*" // v6.2.5
    },
    "require-dev": {
        "doctrine/doctrine-fixtures-bundle": "^3.4", // 3.4.2
        "mtdowling/jmespath.php": "^2.6", // 2.6.1
        "phpunit/phpunit": "^9.5", // 9.6.3
        "symfony/browser-kit": "6.2.*", // v6.2.5
        "symfony/css-selector": "6.2.*", // v6.2.5
        "symfony/debug-bundle": "6.2.*", // v6.2.5
        "symfony/maker-bundle": "^1.48", // v1.48.0
        "symfony/monolog-bundle": "^3.0", // v3.8.0
        "symfony/phpunit-bridge": "^6.2", // v6.2.5
        "symfony/stopwatch": "6.2.*", // v6.2.5
        "symfony/web-profiler-bundle": "6.2.*", // v6.2.5
        "zenstruck/browser": "^1.2", // v1.2.0
        "zenstruck/foundry": "^1.26" // v1.28.0
    }
}

What PHP libraries does this tutorial use?

// composer.json
{
    "require": {
        "php": ">=8.1",
        "ext-ctype": "*",
        "ext-iconv": "*",
        "api-platform/core": "^3.0", // v3.1.2
        "doctrine/annotations": "^2.0", // 2.0.1
        "doctrine/doctrine-bundle": "^2.8", // 2.8.3
        "doctrine/doctrine-migrations-bundle": "^3.2", // 3.2.2
        "doctrine/orm": "^2.14", // 2.14.1
        "nelmio/cors-bundle": "^2.2", // 2.2.0
        "nesbot/carbon": "^2.64", // 2.66.0
        "phpdocumentor/reflection-docblock": "^5.3", // 5.3.0
        "phpstan/phpdoc-parser": "^1.15", // 1.16.1
        "symfony/asset": "6.2.*", // v6.2.5
        "symfony/console": "6.2.*", // v6.2.5
        "symfony/dotenv": "6.2.*", // v6.2.5
        "symfony/expression-language": "6.2.*", // v6.2.5
        "symfony/flex": "^2", // v2.2.4
        "symfony/framework-bundle": "6.2.*", // v6.2.5
        "symfony/property-access": "6.2.*", // v6.2.5
        "symfony/property-info": "6.2.*", // v6.2.5
        "symfony/runtime": "6.2.*", // v6.2.5
        "symfony/security-bundle": "6.2.*", // v6.2.6
        "symfony/serializer": "6.2.*", // v6.2.5
        "symfony/twig-bundle": "6.2.*", // v6.2.5
        "symfony/ux-react": "^2.6", // v2.7.1
        "symfony/ux-vue": "^2.7", // v2.7.1
        "symfony/validator": "6.2.*", // v6.2.5
        "symfony/webpack-encore-bundle": "^1.16", // v1.16.1
        "symfony/yaml": "6.2.*" // v6.2.5
    },
    "require-dev": {
        "doctrine/doctrine-fixtures-bundle": "^3.4", // 3.4.2
        "mtdowling/jmespath.php": "^2.6", // 2.6.1
        "phpunit/phpunit": "^9.5", // 9.6.3
        "symfony/browser-kit": "6.2.*", // v6.2.5
        "symfony/css-selector": "6.2.*", // v6.2.5
        "symfony/debug-bundle": "6.2.*", // v6.2.5
        "symfony/maker-bundle": "^1.48", // v1.48.0
        "symfony/monolog-bundle": "^3.0", // v3.8.0
        "symfony/phpunit-bridge": "^6.2", // v6.2.5
        "symfony/stopwatch": "6.2.*", // v6.2.5
        "symfony/web-profiler-bundle": "6.2.*", // v6.2.5
        "zenstruck/browser": "^1.2", // v1.2.0
        "zenstruck/foundry": "^1.26" // v1.28.0
    }
}

Here be dragons! We've built a pretty sweet API for storing dragon treasures... but we've completely neglected one minor detail: security! In this tutorial, we'll secure our API Platform-powered API in every way imaginable... and spin up a nifty test suite along the way:

  • Disabling documentation on production
  • Different types of API authentication
  • Logging in via Ajax & sessions
  • Creating an API Token system with "scopes"
  • Securing your API resources
  • Bootstrapping tests with zenstruck/browser & zenstruck/foundry!
  • How to use PATCH
  • Adding security & securityPostDenormalize to operations & using object
  • Voters
  • Conditional fields based on permissions: #[ApiProperty(security: 'is_granted(...)')]
  • Using a "state processor" to hash user passwords
  • Dynamic serialization groups with a ContextBuilder
  • Completely dynamic fields by decorating the normalizer
  • Preventing "not allowed" data with validation
  • Automatically set the "owner" of an object on create
  • Auto-filter collections with "query extensions"

Sheesh! Let's go!

Next courses in the APIs: API Platform 3 section of the APIs Track!

5 Comments

Sort By
Login or Register to join the conversation
Bartlomeij avatar Bartlomeij 8 months ago edited

Hey folks! Just a quick fun fact for those diving into the world of ApiPlatform: If you're playing around with an OpenApiFactoryDecorator, you might have noticed everything works like a charm across dev, test, and prod environments when Swagger is enabled. But, guess what happens when you turn off Swagger docs on, let's say, your prod environment? 🥁... You hit an error! Yup, you'll see something like:

The service "App\ApiPlatform\OpenApiFactoryDecorator" has a dependency on a non-existent service "api_platform.openapi.factory".

But fear not, my fellow Symfony enthusiasts! There's a neat trick to avoid this little hiccup. By tweaking our decorator with a bit of configuration magic, we can tell Symfony to just chill and ignore this decorator when it's not needed. Simply slap on an annotation like this:

#[AsDecorator(
    decorates: 'api_platform.openapi.factory',
    onInvalid: ContainerInterface::IGNORE_ON_INVALID_REFERENCE,
)]

And voilà! No more errors when Swagger decides to take a day off on your prod environment.

3 | Reply |

Cool! Thank you for sharing it @Bartlomeij

| Reply |
hubertinio avatar hubertinio 11 months ago

Hi, thank you very much for this! You help me a lot.

There is only one misunderstunding on the beginng. You provide admin part from the Symfony but in official installation there is next container with pwa in reactjs. Create login form in that like yours was impossible for me.

Thanks and keep going

| Reply |

Hey @hubertinio

I'm afraid I did not fully understand your question. Do you mean that you installed ApiPlatform including the "admin" package? If that's the case yes, you'll find hard (or different) to tweak it to match this tutorial, but the thing here is this tutorial is focus only on the "core" ApiPlatform package, so you should only install that one and follow the tutorial. Or, you can download the starting course code from our site

Cheers!

| Reply |

You are right, I can install that one from the tutorial but I have existing project where admin is in reactjs already

| Reply |

Delete comment?

Share this comment

astronaut with balloons in space

"Houston: no signs of life"
Start the conversation!