Chapters
39 Chapters
|
4:45:13
|
Login to bookmark this video
-
Course Code
Subscribe to download the code!Compatible PHP versions: ^7.1.3, <8.0
Subscribe to download the code!Compatible PHP versions: ^7.1.3, <8.0
-
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!
02.
API Auth 101: Session? Cookies? Tokens?
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!
This tutorial works great for Symfony 5 and API Platform 2.5/2.6.
What PHP libraries does this tutorial use?
// composer.json
{
"require": {
"php": "^7.1.3, <8.0",
"ext-ctype": "*",
"ext-iconv": "*",
"api-platform/core": "^2.1", // v2.4.5
"composer/package-versions-deprecated": "^1.11", // 1.11.99
"doctrine/annotations": "^1.0", // 1.13.2
"doctrine/doctrine-bundle": "^1.6", // 1.11.2
"doctrine/doctrine-migrations-bundle": "^2.0", // v2.0.0
"doctrine/orm": "^2.4.5", // v2.7.2
"nelmio/cors-bundle": "^1.5", // 1.5.6
"nesbot/carbon": "^2.17", // 2.21.3
"phpdocumentor/reflection-docblock": "^3.0 || ^4.0", // 4.3.1
"symfony/asset": "4.3.*", // v4.3.2
"symfony/console": "4.3.*", // v4.3.2
"symfony/dotenv": "4.3.*", // v4.3.2
"symfony/expression-language": "4.3.*", // v4.3.2
"symfony/flex": "^1.1", // v1.21.6
"symfony/framework-bundle": "4.3.*", // v4.3.2
"symfony/http-client": "4.3.*", // v4.3.3
"symfony/monolog-bundle": "^3.4", // v3.4.0
"symfony/security-bundle": "4.3.*", // v4.3.2
"symfony/twig-bundle": "4.3.*", // v4.3.2
"symfony/validator": "4.3.*", // v4.3.2
"symfony/webpack-encore-bundle": "^1.6", // v1.6.2
"symfony/yaml": "4.3.*" // v4.3.2
},
"require-dev": {
"hautelook/alice-bundle": "^2.5", // 2.7.3
"symfony/browser-kit": "4.3.*", // v4.3.3
"symfony/css-selector": "4.3.*", // v4.3.3
"symfony/maker-bundle": "^1.11", // v1.12.0
"symfony/phpunit-bridge": "^4.3", // v4.3.3
"symfony/stopwatch": "4.3.*", // v4.3.2
"symfony/web-profiler-bundle": "4.3.*" // v4.3.2
}
}
10 Comments
I am bulding an api solely for 3rd party applications.
I was thinking of a simple api key authorization system. Is this session/user login based authentication system applicable to me?
If not, which part of this api security course would be most relevant?
Hey Nick!
Apologies for the slow reply - holidays!
The session/user login might be applicable for (1) depending on "who" is making these requests. But for the other items, no, it's not relevant. If you truly have just a single email provider and a single phone provider that need to make requests, you could build a super simple api key system. Heck, you could even hardcode those 1 or 2 tokens into your config - no need to complicate things.
You'll need to build an authenticator for the API token system. But other than that, pretty much the rest of this tutorial is relevant because it is not about authentication, but more about applying authorization rules (i.e. denying access) or returning data based on the user. Well, this will be relevant to you if you have these use-cases. Let me know if you have any questions about the api token authenticator that you'll need to build.
Cheers!
Hi there! I have a tricky question that I haven't figured out how to manage.
Let's say I have two frontends hosted in different subdomains (frontend1.domain.com and frontend2.domain.com) that can login using the same api hosted on another subdomain (api.domain.com).
I want a customer to be able to use both frontends at the same time on the same browser (in 2 different browser tabs), being logged in with two different API users (each user has a different role with different permissions in each frontend), so I need each login to each frontend to be completely independent from the other one.
Here comes the problem: when a customer logs in using the API, the cookie generated is based on the API subdomain (api.domain.com) and not on the frontend subdomain. This causes a big mess when the customer uses both frontends at the same time, because the session cookie is shared in between both frontends.
Is there a way to generate two different session cookies (one per each frontend) to be able to achieve that scenario?
Many thanks in advance for your help!
Pedro
Hey Pedro S. !
Apologies for the slow reply!
Hmm. Yes, I believe what you need to do is change the session cookie name used by each app. By default it is
PHPSESSID, but that can be changed. I believe this can be set inframework.yamlvia:Let me know if that helps.
Cheers!
The make:user that is required for the next chapter is missing in the video
Hey Sridhar,
This is the 2nd tutorial, we created that User entity in the 1st one, exactly here: https://symfonycasts.com/sc... . We based the code of this tutorial on the finish code of the first tutorial, so it's like continuation of the 1st tutorial :)
If you skipped the first tutorial and started from this one - you would need to create User yourself, or we always recommend to code along with us downloading the course code and start from start/ directory - it will contain everything you need to start this course :)
Cheers!
Hi Ryan, I am using API Platform with LexikJWTAuthenticationBundle and Symfony 4.4.
All works but I have no idea how to add some extra data to JWT.
I have configured that bundle to return user email as: user_identity_field, but I would like to add username too.
Documentation seems to be for older version of Symfony:
https://github.com/lexik/Le...
I have also checked: https://symfony.com/doc/cur...
but there are no examples..
Could you advice?
Hey Krzysztof K.!
I can definitely help with this :). The answer is to listen to the "jwt_created" event - I talk a bit about it here: https://symfonycasts.com/screencast/symfony-rest4/jwt-guard-authenticator#comment-4497986969
The docs you linked to - https://github.com/lexik/LexikJWTAuthenticationBundle/blob/master/Resources/doc/2-data-customization.md#eventsjwt_created---adding-custom-data-or-headers-to-the-jwt - I think is up to date. Well, sort of :). The docs are written on a way that would work - but there are easier ways to do things now. Here's what I would do:
1) Run
bin/console make:subscriber2) When it asks for the event name, type in
lexik_jwt_authentication.on_jwt_createdThat will generate the subscriber class for you - not YAML configuration will be needed. Then you can make the method in the subscriber class look like the example in their docs look: https://github.com/lexik/LexikJWTAuthenticationBundle/blob/master/Resources/doc/2-data-customization.md#example-add-client-ip-to-the-encoded-payload
Let me know if you hit any issues :).
Cheers!
Hi,
just a little question on auth strategy, if the client and the API (with no path prefix) are on different domain what would be the best authentification option ?
Hey Joel L.!
Sorry for the slow reply :). I've never had to implement this specifically - so I can't say for sure from a perfectly-educated place :). In theory, you could still use session-based cookie authentication as long as you whitelist your frontend's domain in CORS. However, I "think" that this will simply *not* work with a samesite cookie, which you *do* want to use.
So in this case, you probably would need to use some sort of API token to make authenticated requests to the API. I just don't love this because it means that, on some level, you're going to be needing to "keep track of" something sensitive - like an API token - in JavaScript. If you're careful and just keep it on a scoped JavaScript variable, I think you're ok (but "I think" is not a strong statement in security). However, even if that's true, unless you truly *store* it somewhere (like local storage or a cookie that JavaScript can read) then when you refresh, it will be gone and the user won't be authenticated. But as soon as you "store" something sensitive in JavaScript, you're asking for trouble. Basically, I think you're on shaky ground here, and it's why having some backend that's on the same domain as you is super handy... even if that backend itself is just making requests to some other API (but then it can securely store the authentication info, instead of JavaScript).
I hope this helps! Tough stuff :/
"Houston: no signs of life"
Start the conversation!