Supabase Auth: SSO, Mobile, and Server-side support
Tags: supabase, opensource, authentication, programming
Published: 2023-04-13 16:08:32

Today we're excited to announce a few new features for Supabase Auth:

1. Easily add Single Sign-On support to your projects using SAML 2.0
2. Better support for server-side rendering and mobile apps using PKCE
3. Native Apple login on iOS

## Single Sign-On Support using SAML 2.0

With Single Sign-On (SSO), your users can login with their company's identity provider (IDP), a critical feature when you're building applications for Enterprises.

Every developer building a B2B application eventually needs the SSO authentication flow to onboard enterprise customers. SSO is a requirement for larger Enterprise customers because it's a standard request in Enterprise Security Policies. Over the past few months, we've been [dogfooding SSO for our own Enterprise customers](https://supabase.com/docs/guides/platform/sso), and today we're releasing it for you to do the same.

Building SSO into your application isn't necessarily hard, but does come with some complexity. A lot of time can be spent understanding the nuances and details of the protocol - from dissecting the jargon to testing the implementation heavily. It took us months to build it for ourselves. With this release, you will have SSO set up and running in less than an hour so that you can focus on shipping the core features of your product. This feature is available for the [Pro-tier and above](https://supabase.com/pricing), starting today. It will also be available on the [self-hosted version](https://supabase.com/docs/guides/self-hosting).

{% youtube hAwJeR6mhB0 %}


### Getting Started with SAML 2.0

To get started, enable the [“SAML 2.0“](https://app.supabase.com/project/phcnitosaawbzytgyznx/auth/providers) [authentication method in the dashboard](https://app.supabase.com/project/_/auth/providers). We've added new commands to the [Supabase CLI](https://supabase.com/docs/guides/cli) to help with the configuration process:

```bash
$ supabase sso --help
Manage Single Sign-On (SSO) authentication for projects

Usage:
  supabase sso [command]

Available Commands:
  add         Add a new SSO identity provider
  info        Returns the SAML SSO settings required for the identity provider
  list        List all SSO identity providers for a project
  remove      Remove an existing SSO identity provider
  show        Show information about an SSO identity provider
  update      Update information about an SSO identity provider
```

Once you've added a new SSO identity provider to your project, it's as simple as calling the `signInWithSSO()` from the `supabase-js` library:

```tsx
const { data } = await supabase.auth.signInWithSSO({ domain: 'acme.corp' })

if (data.url) window.location.href = data.url
```

### SSO with Row Level Security and multi-tenancy

As usual, we've engineered this feature around the excellent capabilities of PostgreSQL.

For example, you can use Row Level Security (RLS) to build multi-tenant applications, simply by using the provider's unique identifier in the user's JWT:

```sql
create policy "Only allow read-write access to tenants" on tablename as restrictive to authenticated using (
  tenant_id = (auth.jwt () -> 'app_metadata' ->> 'provider')
);
```

The journey to enterprise readiness isn't an end goal, it is a continuous process that demands constant attention and maintenance. With Supabase Auth, your team can offload this engineering burden to us and prioritize the features that matter.

## Server-Side and Mobile Auth

Many developers today are using Supabase to build mobile apps, and server-side rendering is becoming popular (again!). This release will add support for these use cases by introducing the _Proof Key for Code Exchange flow (PKCE)_ authentication flow. This improves security for mobile apps and makes building server-first apps simple. Since this is a major update that touches many of the authentication routes, we will be rolling it out gradually over the next few weeks.

### A brief history of Supabase Auth

When we [launched](https://news.ycombinator.com/item?id=24072051) Supabase Auth, our target was JAMstack developers. In these cases, the protocol used between the user's application and Supabase Auth is known as the [Implicit Grant Flow](https://www.rfc-editor.org/rfc/rfc6749#section-4.2):

![Supabase Auth implicit grant flow](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/pq8617vrz1qavn374sgg.png)

As developers built more complex apps, they encountered two problems with this authentication flow:

- **Server-Side Email Verification Links**
  Data provided in a URL fragment is only accessible in a browser environment, not on the server. This is problematic for email verification links that redirect users to a server-side route.
- **Challenges with Mobile App Authentication**
  The implicit grant flow raised security concerns for mobile use cases since [malicious apps could potentially obtain the user session](https://www.rfc-editor.org/rfc/rfc7636#section-1).

Server-side auth unlocks a number of benefits. Developers can:

- Set cookies on the same domain as the application.
- Enable server-side rendering for protected pages.
- Perform downstream actions after user authentication, such as adding the user to a CRM or sending analytics.

### Introducing PKCE

To solve these problems, we're introducing support for the _Proof Key for Code Exchange_ flow (PKCE, pronounced “pixy”).

The PKCE flow introduces a _code verifier_ (a randomly generated secret) and a _code challenge_ (the hash of the _code verifier_). The authorization code is returned as a query parameter so it's accessible on the server. During the PKCE flow:

1. The _code challenge_ is sent to Supabase Auth, which returns an _authorization code._
2. The client sends the _authorization code_ together with the _code verifier_ to obtain the user's session.
3. Supabase Auth checks if the _code verifier_ matches the _code challenge_ sent earlier by computing the hash. This renders a malicious attacker's attempt to intercept the authorization code useless, since they need to know the value of the _code verifier_ as well.

![Supabase Auth PKCE Flow](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/82tdcvmfq2rgxezzt649.png)

### Migrating to PKCE on the client

Over the next few weeks, you'll be able to use it with the Supabase libraries. We've already added PKCE to the [JavaScript](https://supabase.com/docs/reference/javascript/installing) client library and our [auth-helpers](https://supabase.com/docs/guides/auth/auth-helpers) library. If you're using `supabase-js` , you can switch to PKCE by initializing your client with the following option:

```tsx
import { createClient } from '@supabase/supabase-js'

const supabase = createClient(SUPABASE_URL, SUPABASE_ANON_KEY, {
  auth: {
    flowType: 'pkce',
  },
})
```

For client-side auth, that's all you need to do to switch over. `supabase-js` will handle the generation and storage for the code verifier, as well as exchanging the authorization code for the user's session.

### Migrating to PKCE on the server

Server-side authentication is now a lot easier. Let's look at an example using NextJS.

Install the `next` version of auth-helpers (lets use the `nextjs` version for this example)

```bash
npm install @supabase/auth-helpers-nextjs@next
```

Then prepare an endpoint for the sign in process. The redirect URL is set to `/api/auth/callback`, which will be implemented next.

```tsx
// api/auth/login
import { NextApiRequest, NextApiResponse } from 'next'
import { createServerSupabaseClient } from '@supabase/auth-helpers-nextjs'

export default async function handler(req: NextApiRequest, res: NextApiResponse) {
  // Create the Supabase Client
  const supabase = createServerSupabaseClient(
    { req, res },
    {
      supabaseUrl: process.env.SUPABASE_URL,
      supabaseKey: process.env.SUPABASE_ANON_KEY,
    }
  )

  // Start sign in with one-time password
  const { error } = await supabase.auth.signInWithOtp({
    email: 'foo@example.com',
    options: {
      emailRedirectTo: 'http://localhost:3000/api/auth/callback',
    },
  })

  if (error) {
    res.json(JSON.stringify(error))
  }

  res.redirect('/')
}
```

Now we can set up the callback API endpoint:

```tsx
// api/auth/callback
import { NextApiRequest, NextApiResponse } from 'next'
import { createServerSupabaseClient } from '@supabase/auth-helpers-nextjs'

export default async function handler(req: NextApiRequest, res: NextApiResponse) {
  // Create authenticated Supabase Client
  const supabase = createServerSupabaseClient(
    { req, res },
    {
      supabaseUrl: SUPABASE_URL,
      supabaseKey: SUPABASE_ANON_KEY,
    }
  )
  // check for code in url querystring
  const code = req.query.code

  if (typeof code === 'string') {
    // exchange the auth code for user session
    await supabase.auth.exchangeCodeForSession(code)
  }

  // redirect the user to a server-side protected area in your app
  res.redirect('/')
}
```

### Roll out

Since this is a major update that touches many of the authentication routes, we will roll it out gradually over the next few weeks. You will receive a notification in your dashboard when the feature is available for your project. Reach out to us if you want early access to this feature.

## Native Apple login on iOS

While PKCE support is great, that is not the only news for you mobile app developers out there.

Building apps for iOS requires support for native _Sign in with Apple_. We heard the community's requests for native sign-in. We hope you join our excitement to officially announce support for native _Sign in with Apple_.

Your app's iOS Bundle ID can now be configured in the Apple provider section of your project's dashboard.

![Native Apple login on iOS](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/0i01lxy6gtkwo5abwe07.png)

This is the only prerequisite for triggering a native _Sign in with Apple._ With [supabase-flutter](https://pub.dev/packages/supabase_flutter#native-sign-in-with-apple-example), this is as easy as:

```dart
final AuthResponse response = await supabase.auth.signInWithApple();
```

It's that easy! No need to set up deep links, no need to pass any parameters.

We're just starting with Apple login, and soon add support for Google login.

## Wrapping Up

Supabase Auth aims to continue developing auth features that are secure by default yet simple to implement. We use Supabase Auth for our hosted platform and continuously dogfood the latest version on it. If you are interested to migrate to Supabase Auth, you can check out this blog post on how [Parqet migrated 125,000 users from Auth0 to Supabase Auth](https://kevcodez.medium.com/migrating-125-000-users-from-auth0-to-supabase-81c0568de307).

## More Launch Week 7

- [Day 3: Supabase Storage v3: Resumable Uploads with support for 50GB files](https://supabase.com/blog/storage-v3-resumable-uploads)
- [Day 2: Supabase Edge Runtime: Self-hosted Deno Functions](https://supabase.com/blog/edge-runtime-self-hosted-deno-functions)
- [Day 1: Supabase Logs: open source logging server](https://supabase.com/blog/supabase-logs-self-hosted)
- [The Supabase AI Hackathon](https://supabase.com/blog/launch-week-7-hackathon)
- [Supavisor](https://github.com/supabase/supavisor)
- [Designing with AI: Generating unique artwork for every user](https://supabase.com/blog/designing-with-ai-midjourney)

{% cta http://supabase.com?utm_source=devto&utm_medium=referral&utm%5C_term=devtocta %} 🚀 Learn more about Supabase {% endcta %}