iOS Passwordless Chat Application with Auth0

Almost every application needs an authentication strategy. The most common being the classic username and password combo. However, there's a new approach some apps are taking to avoid handling or storing user passwords: passwordless authentication. It generally involves sending a one-time PIN (OTP) through a user-owned channel such as their phone or email. If the user inputs the correct PIN, we give them access to the system.

In this article, we'll build an iOS chat application with Stream Chat, for its fully featured iOS chat components and Auth0's passwordless features for authentication.

You can see the final result in the screenshot below and download the complete source code in the Passwordless Chat App iOS GitHub repository. Let's dive in!


To follow this tutorial, create an account with Stream, Auth0, and Ngrok. You'll also need Xcode, NodeJS, and Ngrok installed.

Stream takes care of the chat features, Auth0 provides the passwordless authentication we need, and Ngrok lets us quickly expose our local NodeJS backend to the external world via HTTPS.

Auth0's free plan includes the passwordless feature, and if you're an independent developer or with a small team, you may be eligible for Stream's free maker account. So, remember to sign up for it!

Create iOS Project

Since we'll need some details of the iOS project to configure the Auth0 dashboard, let's first create a UIKit project on Xcode with the UIKit App Delegate lifecycle.

Configure Auth0 Account

Before we can dive into the code, let's visit our Auth0 account to enable passwordless authentication and get the credentials we need.

After you've created your Auth0 account and you're in the dashboard, go to Authentication > Passwordless and enable "Email". Also, make sure to set the Default App’s switch to “on” for passwordless authentication in the Applications tab. You can also use SMS if you have a Twilio account.

After you've enabled Email authentication, go to your Default App in Applications and copy your Domain and Client ID. We'll need these later in the iOS code section.

After that, scroll a bit down to Application Properties and change your application type to Native.

Once that's done, scroll further down to Advanced Settings > Device Settings and paste your Team ID (DEVELOPMENT_TEAM) and App ID (PRODUCT_BUNDLE_IDENTIFIER), which you can find in your Xcode .pbxproj file, which is contained within the .xcodeproj file. To reveal the .pbxproj file, right click the .xcodeproj file and select Show Package Contents.

Next, move to the Grant Types tab, enable Passwordless OTP, and hit save.

After that, move to the Certificates tab, download your PEM certificate, name it public.pem, and place it in the same folder as your backend's index.js. You will use this certificate to verify the authentication request in your backend.

Create Backend Project

The backend consists of a single endpoint that generates a Stream JWT for a given user id. When the iOS app makes this request, it must also include an Auth0 ID Token to be verified. If the verification fails, we return 401 (Unauthorized) instead of the token. If it succeeds, we produce the Stream token, thus providing our user access to the chat feature under the given user id.

Install the dependencies with npm install express stream-chat jsonwebtoken --save or yarn add express stream-chat jsonwebtoken, then run your backend with node index.js.

Using Ngrok

To access this endpoint outside our local machine and serve it under HTTPS (ideal for iOS apps), we can use Ngrok. You can install Ngrok through homebrew by running the command brew install ngrok, or visit the Ngrok website. You'll also need an account and the auth token set up.

After you have Ngrok and your account set up, run ngrok http 3000. If your backend is running on a different port than 3000, make sure to use that number instead. After you run the command, you should copy the https URL. You'll need it in the next section.

iOS Dependencies

Add the following dependencies to your iOS project.

You can install the dependencies with Xcode's built-in Swift Package Manager integration or CocoaPods.

iOS Code

First, we need code to ask our backend for the JWT. You can write a stand-alone function that does it like below. Remember to replace the Ngrok URL. You can paste the function anywhere you want. For example, you can create a fetchStreamJWT.swift file and paste it there.

After that, we also need a function that creates our Chat's UI stack. After reading Stream Chat's iOS Tutorial, we can quickly write a stand-alone function that sets up our UI. As with the last function, you can create a makeChat.swift file and paste it there.

In the ViewController.swift file, we'll use Auth0's Lock.swift SDK to show the authentication UI. Once the user inputs the OTP, the onAuth callback is triggered, giving us the Auth0 ID token. We then call fetchStreamJWT to hit our endpoint and makeChat to display our chat UI.

Testing Your App

If everything is right and your backend is running, you should be able to run your project in a device or simulator. Type in your email, and you'll receive a code. After typing the code correctly and pressing submit, it will take you to the chat screen.

Next Steps with the Passwordless Chat App

Congratulations! You've built the basis of a functioning passwordless chat app with Stream Chat and Auth0. I encourage you to browse through Stream Chat's docs, Auth0's iOS passwordless docs, and experiment with the project you just built. Good luck on your app development!