Last week I kicked off a new stream series in which we’re going to take a look at Azure Communication Services (ACS).
Well, the first episode is out and I wanted to document what we learnt with building on ACS.
Setting the scene
ACS is essentially the backend for Teams, but provided in a way that you can integrate it into your existing applications. For our case, we’re building from scratch and the target deployment is going to be Azure Static Web Apps (SWA) as this will give us an API backend (for user management), a host for our React front end and most importantly, account management.
For the codebase, we’re starting with a React TypeScript GitHub template that I’ve created for SWA, with the API backend written in TypeScript Azure Functions.
Giving users access
One thing that is really awesome about ACS is that you bring your own authentication model, meaning that you aren’t being forced to port your application to Azure AD or anything, but it does raise the question, how do you grant the user access?
Well, this is where the API backend that we’re using in SWA comes into play, you need a token service that will issue tokens for the users, however your representing them. Let’s take a look at how to do that.
Creating a token service
We’ll use a HTTP Trigger to do this, and it’ll live at
/api/issueToken. Start by creating that within the
api folder of the Git repo:
In our Function, the first thing that we’ll do is the ensure that there is a logged in user. SWA provides a mechanism to do that via its config file, but we also want to get access to the user profile and validate it (we won’t use the profile yet, but in the future we will).
Time to remove the boilerplate Function code and start putting in ours:
Here we’re unpacking the header and ensuring that there is a
userId in the principal, if not, then we’ll return bad request.
Now we’re going to integrate the the ACS administration npm package,
@azure/communication-administration which gives us the ability to issue a token for the user. This token is then used in the client application to connect with ACS and do whatever we’re allowing the client to do.
With the package installed, we can incorporate it in and issue our token. To do that we need to create a
CommunicationIdentityClient, in which we provide the connection string to ACS.
If you haven’t created an ACS resource yet, check out the docs.
I’ve added a connection string to the
local.settings.json, as per Azure Functions docs called
COMMUNICATION_SERVICES_CONNECTION_STRING that gives me access to ACS.
identityClient is ready, we can use it within the Function:
The important lines from above are these two lines:
The first is creating a user in ACS. Notice how this user doesn’t have any direct relationship to the user account we’ve got in our system already. This does mean that we’re creating a whole new user each time that we want a token, rather than associating the ACS user with our systems user, so down the track we’re going to need to work out how to do that more effectively, but this is ok for the moment. Once we have our
CommunicationUser we then call the
issueToken method, and provide it with the scopes that we want the user to have, in this case the token will only allow them to have VOIP capabilities, but if you wanted them to have chat as well, then you’d need to explicitly grant them that.
But with that, our backend is done and we’re able to issue tokens for the client application.
This isn’t everything that we managed to get to in the first episode, but it is the most important thing because once we can issue tokens we can start to build up the client application. You’ll find the code in the
part-01 tag on GitHub, and you can watch the whole episode on YouTube. Nex time, we’re going to start displaying camera feeds and accessing the microphone.