Keyri
Keyri can be used to incorporate sign-in-with-QR functionality into your Supabase app, allowing users to scan a QR code on your web app with your mobile app and be instantly logged into the web app without having to input any credentials.
Configuration is split into Web and Mobile components. On web, the Keyri QR Widget needs to be installed along with an event listener, and in your mobile app, install the Keyri SDK and pass into it the user's refresh token when sign-in-with-QR is initiated. When the refresh token lands in your web app, it's passed into Supabase's setSession()
method.
Sign up for Keyri
First make a free account on the Keyri dashboard (https://app.keyri.com). On Add Your Application, set a name and input the domain on which your app will eventually be deployed. You can create multiple application in Keyri to account for your development, staging, and production environments
Note your application key from the Keys and Credentials section - this will be used in the Mobile portion of the implementation
Web
For your web app, first download KeyriQR.html (available here) and save it to a public directory.
Next, embed KeyriQR.html in your login page as an iFrame within the desired div. This serves as the widget that displays the dynamic QR code and connects with the Keyri API.
<div>
<iframe
title='KeyriQR'
src='/KeyriQR.html'
id='qr-frame'
height='300'
width='300'
scrolling='no'
style={{ border: 'solid 5px white' }}
></iframe>
</div>
Next, for the same login view, set up an event listener to pick up the session token that the iFrame emits when the QR code is scanned by your app.
useEffect(() => {
window.addEventListener('message', async (evt) => {
if (evt.data.keyri && evt.data.data && document.location.origin == evt.origin) {
const { data } = evt;
if (!data.error) {
let refresh_token = JSON.parse(data.data).refreshToken;
await handleQrLogin(refresh_token);
} else if (data.error) {
console.log(`Keyri error: ${data.message}`);
}
}
});
That's it!
Mobile
Install Flutter#
First, install the Flutter SDK, found at flutter.dev
Make sure to add Flutter to your PATH, for example:
export PATH="$PATH:`pwd`/flutter/bin"
Apple - initial setup#
Download the latest version of Xcode from the Mac App Store. Make sure the Xcode provided simulator is using a 64-bit device (iPhone 5s or later). You can check the device by viewing the settings in the simulator’s Hardware > Device or File > Open Simulator menus.
Android - initial setup#
Download the latest version of Android Studio. Install Android SDK and needed emulator(s).
Create Project#
Run this command in your terminal/shell at the desired location for your new project
$ flutter create my_app
You can then CD into the new directory, and run the test app with
flutter run
This is a good test - if things are configured correctly so far you should see the default Flutter test app deployed.
Add dependencies (Keyri and Supabase)#
Open your Pubspec.yaml file, which should be at the top level directory in your new project
Add Keyri and Supabase under dependencies
One can now access Supabase and Keyri sdks in their Flutter code
Utilize the two together#
- Make a request to Supabase to authenticate the user
- Parse the response to extract the token
- Authenticate using Keyri
- Below, we show how to utilize the EasyKeyriAuth function, which takes the user through scanning the code, creating the session, displaying the confirmation screen, and finalizing the payload transmission
- Note - you can find your App Key in the Keyri Developer Portal
- Alternatively, intermediate functions in the Keyri SDK, discussed in the mobile docs, can provide control over displaying a custom QR Scanner and/or Confirmation screen
- Below, we show how to utilize the EasyKeyriAuth function, which takes the user through scanning the code, creating the session, displaying the confirmation screen, and finalizing the payload transmission
// Sign in user with email and password // Alternatively one can utilize the Supabase API to accomplish the same thing final response = await client.auth.signIn(email: 'email', password: 'password'); if (response.error != null) { // Error print('Error: ${response.error?.message}'); } else { // Success final session = response.data; // This is the payload that needs to be send through Keyri final refreshToken = session.refreshToken // EasyKeyriAuth guides the user through scanning and parsing the QR, confirming the session, and configuring the payload // One can also use the initiateQRSession method to use the Keyri Scanner with a custom Confirmation screen // Or the ProcessLink method if you have your own scanner or are using deep linking await keyri .easyKeyriAuth([App Key], '{"refreshToken":"$refreshToken"}', [email]) .then((authResult) => _onAuthResult(authResult)) .catchError((error, stackTrace) => _onError(error)); }