Supabase Auth now supports Anonymous Sign-ins

4 min read Original article ↗

Supabase Auth now supports anonymous sign-ins, one of our most-requested features by the community.

Anonymous sign-ins can be used to create temporary users who haven’t signed up for your application yet. This lowers the friction for new users to try out your product since they don’t have to provide any signup credentials.

You can enable anonymous sign-ins for your project today from the dashboard:

For local development, upgrade your Supabase CLI and add the config to the config.toml file:


_10

[auth]

_10

enable_anonymous_sign_ins = true


You can create an anonymous user through the Javascript, Flutter or Swift SDKs today. Here’s how you can create an anonymous user using supabase-js .


_10

const { data, error } = await supabase

_10

.auth

_10

.signInAnonymously()


Profiles created with anonymous sign-ins are also authenticated!

Once you call .signInAnonymously() you have moved the user into an authentication flow, and we treat them like a signed in user:

Like a permanent user, anonymous users are persisted in the auth.users table:

idroleemailis_anonymous
e053e470-afa1-4625-8963-37adb862fd11authenticatedNULLtrue
5563108e-ac81-4063-9288-4f3db068efa1authenticatedluke@starwars.comfalse

An anonymous user can be identified by the is_anonymous claim returned in the user’s JWT, which is accessible from your Row Level Security policies (RLS). This is helpful if you want to limit access to certain features in your application.

For example, let’s say that we have an online forum where users can create and read posts.

Given this table to store the posts:


_10

create table public.posts (

_10

id serial primary key,

_10

name text not null,

_10

description text

_10

);


If we only want to allow permanent users to create posts, we can check if the user is anonymous by inspecting the JWT select auth.jwt() ->> 'is_anonymous'.

Using this function in an RLS policy:


_10

create policy "Only permanent users can create posts"

_10

on public.posts

_10

for insert

_10

to authenticated -- Note: user is still authenticated

_10

with check (

_10

(select auth.jwt() ->> 'is_anonymous')::boolean is false

_10

);


RLS gives us full flexibility to create a variety of rules.

For example, to allow read access for permanent users for all posts and limit anonymous users to posts created today:


_12

create policy "Limit access to anonymous users"

_12

on public.posts

_12

for select

_12

to authenticated -- Note: user is still authenticated

_12

using (

_12

case

_12

when (select (auth.jwt() ->> 'is_anonymous'))::boolean is true

_12

then (created_at >= current_date)

_12

else

_12

true

_12

end

_12

);


At some point, an anonymous user may decide they want to create a post. This is where we prompt them to sign up for an account which converts them to a permanent user.

Supabase Auth provides 2 ways to achieve this:

  1. Link an email or phone identity
  2. Link an OAuth identity

To link an email or phone identity:


_10

const { data, error } = await supabase

_10

.auth

_10

.updateUser({ email })


To link an OAuth identity to an anonymous user, you need to enable manual linking for your project. Learn about how identity linking works with Supabase Auth.

Once enabled, you can call the linkIdentity() method:


_10

const { data, error } = await supabase

_10

.auth

_10

.linkIdentity({ provider: 'google' })


When creating RLS policies to differentiate access for an anonymous user, you can leverage the user impersonation feature in the SQL editor to test out your policies:

The user management screen provides an option to filter by anonymous users, which can help to know how many anonymous users have been created.

Managing anonymous users can be tricky, especially when you have a lot of visitors to your site. We’re working on an “automatic clean-up” option to delete anonymous users that have been inactive for more than 30 days. In the meantime, since anonymous users are stored in the auth schema in your database, you can clean up orphaned anonymous users by running the following query:


_10

-- deletes anonymous users created more than 30 days ago

_10

delete from auth.users

_10

where is_anonymous is true and created_at < now() - interval '30 days';


We are also working on a linter to check your RLS policies and highlight those that allow anonymous users access - stay tuned for updates later this month!