Generating JWT Tokens | ASP.NET 6 REST API Following CLEAN ARCHITECTURE & DDD Tutorial | Part 2

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
hi everyone and welcome to part two of my series of building a rest api completely from scratch following clean architecture and domain-driven design principles i do have a quick disclaimer before we begin so i am a microsoft employee and these are microsoft technologies but i'm not talking on behalf of microsoft these are my personal opinions so with that out of the way let's get started so in part one we started setting up a bit of authentication today we're going to take it a step further and implement the jwt token generator we'll then use the options pattern to inject the jwt settings and then we'll see how we can use the net user secrets feature to store our secrets during development so this is a pretty cool feature which many dot net developers aren't aware of so i hope you're going to like that and lastly we're going to sneak peek debugging in visual studio code which we'll go into more in depth in part three all right so we had the two endpoints which make our request to the authentication controller and from there to the authentication service in the application layer today what we're going to be doing is using the jwt token generator which from the point of view of the application layer is just using the interface getting a token and returning it to the user but the actual implementation sits over here in the infrastructure layer okay so as we said over here in the application layer we're going to be defining our interface and over here in the infrastructure we're going to have the implementation and when configuring our services then we'll wire everything up over here in the dependency injection inside the infrastructure layer okay so let's get started so the first thing we want to do is create a common folder where inside here we'll have all of our interfaces let's go ahead and create also authentication inside here and here we'll define our interface so i jwt token generator okay so public interface yes that and let's give it a single method yes generate token but this is a guide and let's also give it the first name and the last name yes that looks good next let's go to let's go to the authentication service and already use it as if it works so in the actual result what we want to do here is first check and if user already exists yes that's what i want to do right so we have the email which is unique we want to check in the database that there isn't a user with the same email if yes then we don't want to register the user again so that's the first thing we want to do then we want to create a user where as part of this will generate a unique id right so generate unique id and then create the token so let's go ahead and use the jwt token generator interface that we just defined so private read only i jw token generator yes this thank you let's inject it in the constructor and use it over here right so bar token equals that seems right and let's actually pull this to a variable all right let's call this user id put it over here and this is just an intermediate implementation right and then we can return the token from here okay next we want to go to the infrastructure layer and create here authentication over here we'll have an implementation jwt token generator yes capital and i kwt token generator yes let's implement the interface and okay so what do we want here first of all we want our claims start with that so yes yes gotta love github co-pilot that's okay now this isn't recognized so let's see where this comes from so ctrl shift p reverse package search and here it is so let's go ahead and add that so that net add to the infrastructure project the package system that identity model yes now that we have that let's add it here let's put the user id right this is just a random guide and let's also add here the given name and the last name family name where this will be the first name and this will be the last name right so okay now the next thing we want to do is create the security token so let's go ahead and say security token equals new jwt security token and let's give it the claims this of course isn't enough we want to also sign the token so let's go ahead and create the sign credentials this will be e yes yes add this and this this seems to be at least 256 bits so that's 16 bytes so let's go ahead and do and super secret key which is exactly 16 right and let's go ahead and add it over here so signing credentials finding credentials the next thing we want to do is add the issuer so in this case we're the issuer let's say issuer and say yes it's us i say expires in yeah why not for now we're going to change this soon and obviously we don't want to use daytime so soon we'll replace this with an injected i daytime provider and that's it let's return it return yes thank you and i have a typo here let's fix this signing yes it seems right okay so i just want to note that over here we're using a symmetric key and that's because we're basically acting both as the token issuer and later we're going to be authenticating the the users so it makes sense that we'll just use metro key because we're just going to be storing the secrets in our service we'll use it also for generating the tokens and later for verifying the tokens but i'm guessing that in your company you probably have an identity server which is in charge of this stuff you're using aad or another solution but this is only to demonstrate the separation of logic between the layers so that's why i chose to add this it's less about the actual implementation that's why i'm not going to be explaining too much about what we're doing over here what claims are and so on so now that we have all this set up so let's go ahead and register over here so services add singleton and yes let's add this from the application layer right and this from the infrastructure layer and that seems about right let's try building the project see that it works let's run it run let's make a register request okay and it seems to work we have here our token now what we can do actually there's an extension called jwt something so let's see what it does let's select the token ctrl shift p and click jwt decoder so basically decode the token and as we expect let's go back to the jwt token generator we can see that we have here what we expected to have right so we have here our claims right so this corresponds to these over here then we have our expiration date which corresponds to this and the issuer which is boober dinner which corresponds to this okay now one more thing about this plugin so for some reason when you use it in this window let's just paste it over here and you select it and run jwt decoder then it doesn't paste it over here but rather now when you hover over it then you can see what it has inside so i'm not sure why this behavior is like this but it is what it is and another thing you can do so if you're not loving this and you you're used to using jwt dot io so you can actually use another extension vs browser which believe it or not this one over here allows you to open a web browser inside visual studio code so let's let's see what this looks like so vs browser style browser and i actually have it set up to sharp lab i o so i can just go over here and use it which is nice but in our case we want to go to jwt dot io and let's make this a bit bigger let's copy and paste our token and boom if you're using visual studio you might be saying oh come on but it's a nice gimmick right okay now that we have that all set up let's go ahead and instead of using over here the daytime let's use the interface let's go to the application layer and define here another folder called services and then here let's create the i datetime provider this is going to be yes only utc now i would recommend either using utc now like this or using daytime offset and now so whichever one you prefer and let's go ahead and implement it over here on the infrastructure layer so services and date time provider public class daytime provider yes that's what we want let's add this perfect and now let's define it over here so services dot at singleton and yes thank you so again the interface is from the application layer and the actual implementation is over here in the infrastructure layer let's go ahead and use it over here in the jwt token generator private read only i daytime provider daytime provider let's go ahead and inject it and over here we can use it right so daytime provider dot utc now dot add minutes 60 something like that okay let's just make sure that this works so run let's make a request and it still seems to work great okay so we finished part one now instead of using these values over here let's use the options pattern to get these values instead of hard coding them over here so let's go to the app settings so it's just over here in the api okay so let's go ahead and create here a new section called jwt settings and yes although we don't actually want here the values sorry minutes let's have this a number not a string issuer yes and audience so we didn't actually add an audience in the current implementation right but we should probably add it so let's go ahead and add it over here let's copy this to the development app settings over here let's put the super secret key from over here expiry minutes we have it over here defined as 60. so let's copy and paste this over here issuer was boober dinner let's copy and paste this over here and the audience let's say also blooper dinner okay so now that we have these values let's create an object to model it so jwt settings dot cs public class jwt settings and yes yes although let's open this side by side right so we have our secret we have very minutes we have the issuer and the audience great let's change all these sets to init and because we have nullable reference types enabled so we got to tell the compiler don't worry well this won't be null and now let's go ahead and configure it over here so to access so to access this section let me just close all of this so to access the section that we just defined we need to use the configurations so let's go back to the program cs let's just close everything so it's more organized let's go to the program cs and when we're calling the infrastructure let's pass the configuration available under builder.configuration and let's add this as a parameter let's wrap this so it's visible and this isn't recognized so let's see where it belongs to so ctrl shift p reverse package search and the first one is what we want so microsoft.extensions.configuration so let's go ahead and add that let's stop our service dot net add to the infrastructure project we want to add the package microsoft dot extensions dot configuration okay now this should be recognized yes let's get rid of this and add this using statement and now we can go ahead and configure so services dot configure yes this is jwt headings so configure actually sits in another package so let's see where it comes from so this is the one that we want actually not the first one so microsoft.extensions extensions let's go ahead and add that so.net add to the infrastructure project the package microsoft dot extension.options dot configuration extensions great let's give it a moment okay so what this line over here does is basically it adds the i options interface where we can request the jwt settings and we'll see how we'll use it in a moment another thing i want to do i saw a nice trick instead of having this string defined over here since this object is modeling this section let's move this as a constant over there so let's go over here to authentication jwt settings and let's say public con string section name yes thank you and jwt settings section name great now in the future we'll look how we can reorganize this stuff a bit so it's so it's more organized because as the project grows then this will become very cluttered there's a few tricks that we can do we'll just explore some of them but that's it in a later video okay so let's go back to the token generator and use the settings so private read-only yes let's inject it but as we said this will be available under the eye options capital o let's let's let's change the name to options and over here let's get the value which is this over here one of the reasons this is great is that now we can easily mock this in our unit tests so let's go ahead and use it so all these places want to replace with this yes secret key i think it's called secret let's replace this with the issuer let's also add here the audience and let's replace this with expiry in minutes and i think that's it right yes looks about right let's make sure this still works make a request and great it still works so you can decode it and see that we have all of our values including the new audience that we just added now we're moving on to the last part of this video which is we can actually get rid of this value over here and add it using the net user secrets feature so let's see how we can use that so i actually want to go to here so you can see it added in real time so.net user secrets init and we need to tell it which project and what this does is it adds this value over here and it creates some file behind the scenes if i'm not mistaken and then when we add now data you'll see it's key value pairs then it's stored in that file and then override the configurations so let's see what this looks like net user secrets that in the project api we want to set so it's jwd settings and secret right so this this matches this route over here with a colon between them and now we need to give it the value so let's say super secret key from user secrets secret okay and here we can see that this was added successfully and we can actually also do instead of set we can have this list and let's get rid of this over here and list all of the secrets that we stored okay so let's go ahead and run this and see how this behaves and i actually want to put a breakpoint in our token generator to see that this actually works so let's put a breakpoint over here and let's make a request okay so it works but we didn't hit the break point and that's because we're just running the project from the command line and it's running in a different process if we want to attach to the running process then we need to do the following things over here in the run and debug so when creating the project you might have a little notification here that says missing assets blah blah you can click here to add them so if you did that then great if you haven't you can just click over here to create a launch json file and in future videos we'll dive deeper into what this does but just for the moment you'll see this adds two options over here dot net core attach and the net core launch which corresponds to this option over here and this option over here and what we want to do is attach the process right so let's choose attach and click play or f5 and here we need to choose the process we want to attach to so that will be boober dinner okay so now that we have the debugger attached let's make a request again so the register let's make the request we hit the breakpoint and over here we can see that the secret is really the value that we put in the user secrets so pretty cool and here there are many options for debugging so we'll talk about this in the future videos that's it for this video i really hope you enjoyed it and have a better understanding on how to separate your logic between the application layer and the infrastructure layer i just want to know that this is really the tip of the iceberg of what we're going to be doing at this project we're going to be covering many concepts especially domain-driven design concepts when we continue in the series so if you're loving this content please make sure to subscribe and i have a very exciting announcement i want to thank my very first patreon lior thank you so much for supporting me i love you and our son it's my wife if you didn't get it so that's it and i'll see you in the next one
Info
Channel: Amichai Mantinband
Views: 51,671
Rating: undefined out of 5
Keywords: dotnet, c#, clean architecture, domain driven design, DDD, jwt, jwt token, .net, .net 6, rest api
Id: 38bQNWKh0dk
Channel Id: undefined
Length: 22min 35sec (1355 seconds)
Published: Fri Jun 10 2022
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.