I did check a lot of videos and tutorials on how to do in this days and now I am literally confused from how many options possible to achieve it, yet none really work well for me. I'm just trying to understand what is the best way for create a simple program structure where a user after login into admin page set creation of a cookie that could expire in 10 minute, but can get refreshed on every access to a page with authorize attribute. That's without the use of Entity Framework btw.
In this days I was experimenting it and I did menage to create cookie using controllers, is that the correct way to create cookie calling the controller function and let it create cookie with await HttpContext.SignOutAsync
? Otherwise I am open to any other suggestion but not point me again to documentations because I did try to understand from there but I get only more and more confused. btw I am working on Net 6.0 at the moment. Thank you for anyone that will point me out on some good resource to understand better this process.
As explained up I did check documentation and tried with the controller method but I want to know if I am doing it right or is a better way in Blazor to menage the user authorization and authentication ? Like ProtectedSessionStorage
?
You cannot set cookies from a Blazor server-side session. You do not have access to the HttpContext and there isn't the traditional request/response cycle that you can use to return cookies in the response headers.
The approach I've has success with is to set up a login form in the usual Blazor way. If the login passes validation then I redirect to a traditional razor page (.cshtml file) that does have access to the HttpContext. After the cookie has been set I then redirect to the post-login page.
The same approach can be taken with logging out.
Below is a basic overview of the process.
<Blazor>
@page "/login"
- Render login form
- Validate user input
- Failure?
- Display error message
- Success?
- Navigate to /dologin
</Blazor>
<Razor>
@page "/dologin"
- validate request
- set auth cookie
- navigate to /post-login
</Razor>
<Blazor>
@page "/post-login"
- validate cookie
- continue session
- ...
- navigate to /logout
</Blazor>
<Razor>
@page "/logout"
- unset cookie
- navigate to post-logout page
</Razor>
<Blazor>
@page "/post-logout"
- continue session
</Blazor>
Obviously this is a simplified representation, and doesn't go into any detail about post-login/logout redirect logic. Nor does it cover what abstraction you are using for auth management. In my project I use SignInManager
from Microsoft.AspNetCore.Identity
, but that is simply my choice of implementation and not related to my choice of workflow.
As described above, after I have validated the username and password, I navigate to the page that sets the auth cookie. Now because this is just another URL, we need to have a trusted way of identifying the authenticated user. We don't want to pass the username and the password in the URL for security reasons. To work around this I create a one-time token in my database after the credentials are validated and associate it with the user and use that to identify the user. I set the token to expire after a short time to improve security.
Relevant steps of the workflow:
<Blazor>
@page "/login"
- Valid credentials?
- Create token for user in database
- Navigate to /dologin?token=ABC123
</Blazor>
<Razor>
@page "/dologin"
- Get token from query string
- Retrieve token from database
- Token valid?
- Delete token from database
- Set auth cookie
</Razor>