Blazor how-to’s: create a chat application – part 2: authentication
Hi All! Welcome to the new episode of the Blazor Chat series. This time we’ll see how we can easily implement simple authentication and how we can see who is online.
Last time we saw how we can use a queue to dispatch the messages to all the users in our chat room. We leveraged the System.Threading.Channels library to act as an in-memory queue and wrote a very quick implementation of our message dispatcher.
In our small sample, we won’t be dwelling much into the realm of authentication.
Identifying a user is far beyond the scope of this series, so I decided to simplify the flow and allow users to enter the chatroom by typing just their username.
<EditForm Model=@_login OnValidSubmit="HandleValidSubmit" class="form-signin"> <h1 class="h3 mb-3 font-weight-normal">Please sign in</h1> <label for="inputEmail" class="sr-only">Username</label> <InputText id="inputEmail" class="form-control mb-4" @bind-Value=_login.Username placeholder="Username" required autofocus /> <button class="btn btn-lg btn-primary btn-block" type="submit">Sign in</button> </EditForm>
Which translates into something like this:
The model class used is just exposing a single property, decorated with some validation attributes:
public class Login { [Required, MinLength(1)] public string Username{get;set;} }
When the user submits the form, the system will store the state in a class and send it to a repository:
public User Login(string username, ConnectedClient client) { var user = new User(username); user.Connect(client); _usersProvider.AddOrUpdate(user); this.UserLoggedIn?.Invoke(this, new UserLoginEventArgs(user)); return user; }
Actually, there’s a bit more going on here. As you might have noticed, we’re storing the username, and link it to an instance of ConnectedClient. We’re also dispatching an event, but we’ll talk more about it later.
Where is this ConnectedClient coming from? Well, from a CircuitHandler! From the official docs:
Blazor Server is a stateful app framework. Most of the time, the app maintains an ongoing connection to the server. The user’s state is held in the server’s memory in a circuit.
With a custom CircuitHandler, we can keep track of the open connections to the server and be informed in case the communication drops (eg. the user closes the browser tab or there’s a network issue).
In our case, we don’t actually need it to authenticate our user. The idea, however, is to link the logged user with the circuit id. This way we can react in case of disconnections and keep track of who is online. Nice isn’t it?
This is basically why our core ChatService class exposes two events, UserLoggedIn and UserLoggedOut. We subscribe to them on the UI and force a refresh every time they get triggered.
That’s all folks! Thank you for reading 🙂