.NET Core 3.0 (Preview 4) Web API Authentication from Scratch (Part 1): Up and Running.
With .NET Core CLI, Entity Framework Core and SQL Server.
Prerequisites
- You need a basic understanding about object oriented programming and C#
- SQL Server pre-installed.
- (Optional) Postman, VS Code.
Note: This article is originally written for .NET Core 3.0 (Preview 4), so in some places you will see
—- version
flag when I install packages. Feel free to install the latest version by removing the—- version
flag, newer versions should work as expected. As an example you can usedotnet add package System.IdentityModel.Tokens.Jwt
instead ofdotnet add package System.IdentityModel.Tokens.Jwt — version 5.4.0
Note 2: I have updated the project to .NET 5.0 which can be accessed from following URL. It’s not a frustrating process, as mentioned earlier make sure packages are at latest version.
Download .NET Core 3.0 Preview from here, currently at 3.0.100-preview4–011223.(2019–05–05). After installation open up a command prompt and type dotnet --info
and that will tell you weather you have installed the SDK correctly.
.NET Core SDK (reflecting any global.json):
Version: 3.0.100-preview4-011223
Commit: 118dd862c8Runtime Environment:
OS Name: Windows
OS Version: 10.0.17763
OS Platform: Windows
RID: win10-x64
Base Path: C:\Program Files\dotnet\sdk\3.0.100-preview4-011223\Host (useful for support):
Version: 3.0.0-preview4-27615-11
Commit: ee54d4cbd2.NET Core SDKs installed:
2.1.202 [C:\Program Files\dotnet\sdk]
2.1.503 [C:\Program Files\dotnet\sdk]
2.1.505 [C:\Program Files\dotnet\sdk]
3.0.100-preview4-011223 [C:\Program Files\dotnet\sdk]
Now let’s create a web api project. Go to the preferred location via cmd and type in dotnet new webapi -o JWTAuth.API -n JWTAuth.API
(-o for specifying output directory and -n for specifying the name of the output directory; you can change them as per your preference.) After the directory structure is created cd
into JWTAuth.API
folder.
We will use Visual Studio Code(and two extensions C# and C# Extensions for code generation and scaffolding) after this point, or any other IDE would work if you don’t want to use VS Code.
Now let’s install Entity Framework Core Preview packages that we will need to work with databases (SQL Server in this case). Inside the JWTAuth.API
directory type these commands.
dotnet add package Microsoft.EntityFrameworkCore.SqlServer -v 3.0.0-preview4.19216.3dotnet add package Microsoft.EntityFrameworkCore.Design -v 3.0.0-preview4.19216.3dotnet tool install --global dotnet-ef --version 3.0.0-preview4.19216.3
Now you can open up VS Code in that directory, then navigate to Controllers
folder. Inside it you will find ValuesController.
When a request reach api/values
it will return “value1”, “value2”. let’s check if that is working properly. If you want to know how to create RESTfull APIs using .NET Core use this guide, since it is out of the scope of this article I’m going to leave it out.
dotnet watch run
dotnet watch
is a tool that runs a .NET Core CLI command when source files change. For example, a file change can trigger compilation, test execution, or deployment. You can however just execute dotnet run
but I prefer using dotnet watch run
because it’s easier that way.
PS D:\My Documents\Tutorials\JWTAuthNETCore3\JWTAuth.API> dotnet watch run
watch : Started
info: Microsoft.Hosting.Lifetime[0]
Now listening on: https://localhost:5001
info: Microsoft.Hosting.Lifetime[0]
Now listening on: http://localhost:5000
info: Microsoft.Hosting.Lifetime[0]
Application started. Press Ctrl+C to shut down.
info: Microsoft.Hosting.Lifetime[0]
Hosting environment: Development
info: Microsoft.Hosting.Lifetime[0]
Content root path: D:\My Documents\Tutorials\JWTAuthNETCore3\JWTAuth.API
Now navigate to http://localhost:5000/api/values or https://localhost:5001/api/values, you will see that values get returned. Use Tabbed Postman extension like me so we can test it out.
So now we know it works. Let’s move on.
Now we need to create database and add some data to it. Assuming you have SQL Server installed, create an empty database in it called (what ever you like but for the sake of this tutorial I’m naming it as) JWTAuthDB.
Now add the connection string to appsettings.json
. It should look like this.
"ConnectionStrings":{
"DefaultConnection":"Server=.;Database=<your database name>;Trusted_Connection=True;ConnectRetryCount=0"
}
Make sure you add the name of your database to Database=<your database name>
.
Now create two folders Data and Models in the JWTAuth.API directory. Inside Models folder add a new c# class Value.cs and inside Data folder add new c# class DataContext.cs, then add following code to those files.
Value model has two fields, which will create a table in our database with two columns, Id and Name when we create the migration and update the database. I hope you know what is a migration is and what is meant by code first approach. If you don’t know all those stuff, that’s fine. Learn it later. In short what we are doing is, creating the models classes first and then use those to create the tables in the database we created. That is what the dotnet-ef
tool does.
Now we need to register the context(DataContext) with dependency injection as a service in Startup.cs
Add following using
statements to the top,
using JWTAuth.API.Data;
using Microsoft.EntityFrameworkCore;
and this line to the ConfigureServices
method.
services.AddDbContext<DataContext>(x => x.UseSqlServer(Configuration.GetConnectionString("DefaultConnection")));
Final Startup.cs
should look like this.
Now run dotnet ef migrations add InitialCreate
this will create a folder named Migrations
and 3 files in it.
Then execute dotnet ef database update
it will create the table in the database.
Full terminal output should look like this.
PS D:\My Documents\Tutorials\JWTAuthNETCore3\JWTAuth.API> dotnet ef migrations add InitialCreate
info: Microsoft.EntityFrameworkCore.Infrastructure[10403]
Entity Framework Core 3.0.0-preview4.19216.3 initialized 'DataContext' using provider 'Microsoft.EntityFrameworkCore.SqlServer' with options: None
Done. To undo this action, use 'ef migrations remove'
PS D:\My Documents\Tutorials\JWTAuthNETCore3\JWTAuth.API> dotnet ef database update
info: Microsoft.EntityFrameworkCore.Infrastructure[10403]
Entity Framework Core 3.0.0-preview4.19216.3 initialized 'DataContext' using provider 'Microsoft.EntityFrameworkCore.SqlServer' with options: None
info: Microsoft.EntityFrameworkCore.Migrations[20402]
Applying migration '20190503225321_InitialCreate'.
Applying migration '20190503225321_InitialCreate'.
Done.
Now let’s add some data, execute the following query. It will insert 3 values to the table, Value 1, Value 2 and Value 3.
USE [JWTAuthDB]
GODECLARE @value INT;
SET @value = 1;WHILE @value <= 3
BEGININSERT INTO [dbo].[Values] ([Name]) VALUES (CONCAT('Value ', @value));
SET @value = @value + 1;END;
Now let’s look at how to get that data using code. First, we need to inject the DataContext
that we created earlier to our Values
Controller. To do that add this lines of code to ValuesController.cs
Make sure to add using JWTAuth.API.Data;
to the top.
private readonly DataContext _context;public ValuesController(DataContext context)
{
_context = context;
}
Now let’s change two Get()
methods so we can access our database.
.
.
.
// GET api/values
[HttpGet]
public async Task<IActionResult> GetValues()
{
var values = await _context.Values.ToListAsync();
return Ok(values);
} // GET api/values/5
[HttpGet("{id}")]
public async Task<IActionResult> GetValue(int id)
{
var value = await _context.Values.FirstOrDefaultAsync(x => x.Id == id);
return Ok(value);
}
Make sure to add,
using Microsoft.EntityFrameworkCore;
As you can see, I renamed the methods as GetValues
and GetValue
and made them both asynchronous using async
keyword and await
keyword. From GetValues()
we are returning all the values in the database, hence ToListAsync()
is used. From the GetValue(int id)
method we are only returning a specific value, selected from the id
parameter passed on to that method. And we have changed the return type of both methods to Task<IActionResult>
. The ActionResult types represent various HTTP status codes. Some common return types falling into this category are BadRequestResult (400), NotFoundResult (404), and Ok (200). Take a look at the documentation.
Now we are ready to test. Head over to postman and send a GET request to the end point that we sent earlier. [https://localhost:5001/api/values]
Let’s try to get a specific value from our table. Send a request to https://localhost:5001/api/values/2 . We are expecting the second value.
Done. If you made this far, you are a genius!. In the next article we will look at password hashing and salting. Happy coding!!