Join Jess Chadwick for an in-depth discussion in this video Implementing basic cookie-based authentication, part of ASP.NET Core: Razor Pages.
- [Instructor] At this point in the course, I've shown you everything you need in order to build a site that allows you to add, edit, and validate data. As well as dynamically rendering that data as HTML. I've even shown you how to selectively lock down individual pages or entire folders from unauthorized access, so not just anyone can come along and modify your data. Now it's time to wrap it all up by implementing basic login capabilities so that you can access those locked down pages and end up with a fully functional application.
I'll start by creating that familiar login page that we all see in our favorite sites. An HTML form that asks for an email address and a password. Since this form is just built with tag helpers and validation that I have already shown you earlier in the course, I'll just copy it from the exercise files, replacing the existing login.cs.html page already in the project. As you can see, it's just a simple form with a couple of input fields built with tag helpers and a little bit of validation.
Those tag helpers are currently giving me an error because they refer to properties on the page model that don't actually exist yet. So with this HTML form in place, let's switch to the page model where the interesting stuff will live. The first thing I'll do is go ahead and add those email address and password properties that the form expects.
And of course, I want Razor Pages to populate them when the login form is posted, so I'll add the bind property attribute on both of them. Then I'll put some validation on them as well. I'll add the required attribute to both to make sure they're not empty. And I'll also add a new data annotation attribute named data type to the password property to tell the tag helpers that this property is a password.
So the tag helper will render a password input field as opposed to a regular one. Likewise, I'll add a display attribute to the email address property to tell the tag helper what name I'd like displayed in the label for this field. Of course I could add more validation here, but I think this gets the point across. Now it's time for the interesting part. Actually authenticating the user when they post their credentials. As in the edit recipe page, I'll replace the on get method with an on post method to process the form post.
Then I'll get to work. Now when it comes to authenticating users, Asp.NetCore provides a wide variety of options that are all well covered in other courses. So I'm not going to get into them here. Instead I'm going to use the simplest way I can think of to validate these credentials. Just make sure they match the user name and password that I expect.
And if they don't match, I'll add my own custom validation error to the model state. To do this, I'll call the add model error method on the model state property, passing it two values. The name of the property that contains an error and the error message I wish to display for that property. But since this error doesn't have to do with any one specific property I'll just use an empty string as the first parameter to indicate that.
Next I can check for any validation errors. And return the user to the form if there are any. With all this in place I can be confident that if I've gotten to this point, my user is valid. So I'll build up an object to represent them.
Because the details of Asp.NetCore security are outside the scope of this course, I'm not going to explain this object in depth. Only that it is the way that I tell Asp.NetCore that the user is authenticated and what their user name is. And finally I can return a special action result called the sign in result by calling the page models sign in method.
And that's it. With this in place I can now run the site and either click on the login button or attempt to hit an authenticated page to be redirected to my login page. At which point I can enter in my credentials. And end up looking at the authenticated add recipe page which proves I'm now logged in. Allowing the user to log out of an authenticated session is even simpler.
Simply add a new page handler. Call the httpContext.SignOutAsync method being sure to pass the authentication scheme that you're being logged out of.
And then finally redirecting the user to the home page. Note that the sign out async method is an extension method and it lives in the Microsoft.AspNetCore.authentication name space. So be sure to import that name space. With this handler in place I can update the logout button on the layout to post to it.
Then I can go ahead and try it out. Since I can see the login button again, that means it works and I've been logged out.
- Creating a new application
- Setting up pages
- Rendering dynamic content
- Reusing markup with layouts
- Increasing the maintainability of pages
- Processing data
- Validating input
- Securing an application