Chapters
37 Chapters
|
3:43:31
|
Login to bookmark this video
-
Course Code
Subscribe to download the code!
Subscribe to download the code!
-
This Video
Subscribe to download the video!
Subscribe to download the video!
-
Subtitles
Subscribe to download the subtitles!
Subscribe to download the subtitles!
-
Course Script
Subscribe to download the script!
Subscribe to download the script!
Scroll down to the script below, click on any sentence (including terminal blocks) to jump to that spot in the video!
Subscribe to jump to this part in the video!
Keep on Learning!
If you liked what you've learned so far, dive in! Subscribe to get access to this tutorial plus video, code and script downloads.
What PHP libraries does this tutorial use?
// composer.json
{
"require": {
"php": ">=8.2",
"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
}
}
8 Comments
Voter dont work on Get Collection.
403
Error: Forbidden
For single resources it works.
Hey @Dejan94!
You're absolutely correct! And that's a really great point to bring up. Suppose you add a
securityattribute like this to yourGetCollection:In this situation, the
objectis actually a "collection" - it's anarrayor maybe a DoctrineCollectionobject, I can't actually remember. The point is: it's not a single object. And that makes sene: if your endpoint returns 10 treasures, you might have access toEDIT5 of them, but not the other 5.So, unfortunately, for the
GetCollectionoperation, if you want to use security to "filter" the collection automatically so that only some are shown, that's not done directly viasecurity. Instead, in chapter 35 (will be released this week - but you can peek at it here https://symfonycasts.com/screencast/api-platform-security/query-extension or download the course code and look at the final directory to see what we did), we create a "query extension" that uses our security logic to modify the query itself to only returns the ones we have access to.Let me know if that helps... or if it didn't ;).
Cheers!
Hmm, I think I've found more to this problem (I'm having the same problem). The first problem (as you mentioned ryan) is: access may be denied for some of the DragonTreasures in the collection. (This is solved by "CH35: Query Extension: Auto-Filter a Collection".)
The second problem (which doesn't seem to have symfonycasts documentation) is that the $subject passed in to the voter isSupports fails because it's a Paginator object of DragonTreasure objects (and not a normal DragonTreasure object).
Have I missed the video on this? I can't seem too find any on Symfonycasts
Would the best way to handle a Paginator object (within the voter) be to pop off a DragonTreasure from the paginators iterable and inspect that (and then assume the rest of the objects in the pagniator are of the same type)?
FYI: there's a response on Stackoverflow that has a different approach for using voters on GET collection endpoints (but loses the ability to inspect the object):
https://stackoverflow.com/questions/59051663/using-symfony-voters-on-collectionoperations-get
Hi Dejan and Ryan
I don't know if is the best option, but for collections, I use a provider to handle it, if the operation is an instance of CollectionOperationInterface I verify in a custom logic if the user is allowed.
Cheers!
I think that's a fine approach. In general, I haven't had this problem. What I mean is, for the GetCollection operation, I either allow access to that endpoint or I don't. Then, based on the user, a query collection extension, I filter it so that they only see the results they want. This means that there is never a time when I need to look at the individual results in the paginator to see if the user should have access: I've already controlled the results in there via the query extension.
It is unfortunate that you need a voter to deny access to a single item & a query extension to control the query to limit results in a collection (i.e. it's unfortunate that you sort of have the security logic in 2 places), but this is the way i handle this :).
Cheers!
Hey Cameron,
I'm happy to hear you were able to solve it yourself, well done!
Cheers!
"Houston: no signs of life"
Start the conversation!