diff --git a/accounts/__init__.py b/accounts/__init__.py
new file mode 100644
index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391
diff --git a/accounts/admin.py b/accounts/admin.py
new file mode 100644
index 0000000000000000000000000000000000000000..8c38f3f3dad51e4585f3984282c2a4bec5349c1e
--- /dev/null
+++ b/accounts/admin.py
@@ -0,0 +1,3 @@
+from django.contrib import admin
+
+# Register your models here.
diff --git a/accounts/apps.py b/accounts/apps.py
new file mode 100644
index 0000000000000000000000000000000000000000..9b3fc5a44939430bfb326ca9a33f80e99b06b5be
--- /dev/null
+++ b/accounts/apps.py
@@ -0,0 +1,5 @@
+from django.apps import AppConfig
+
+
+class AccountsConfig(AppConfig):
+    name = 'accounts'
diff --git a/accounts/authentication.py b/accounts/authentication.py
new file mode 100644
index 0000000000000000000000000000000000000000..a274bb29ae42bdf4c8951bb5dd37b52abcbb07a5
--- /dev/null
+++ b/accounts/authentication.py
@@ -0,0 +1,23 @@
+import sys
+from accounts.models import ListUser, Token
+
+class PasswordlessAuthenticationBackend(object):
+
+    def authenticate(self, uid):
+        print('uid', uid, file=sys.stderr)
+        if not Token.objects.filter(uid=uid).exists():
+            print('no token found', file=sys.stderr)
+            return None
+        token = Token.objects.get(uid=uid)
+        print('got token', file=sys.stderr)
+        try:
+            user = ListUser.objects.get(email=token.email)
+            print('got user', file=sys.stderr)
+            return user
+        except ListUser.DoesNotExist:
+            print('new user', file=sys.stderr)
+            return ListUser.objects.create(email=token.email)
+
+
+    def get_user(self, email):
+        return ListUser.objects.get(email=email)
\ No newline at end of file
diff --git a/accounts/migrations/0001_initial.py b/accounts/migrations/0001_initial.py
new file mode 100644
index 0000000000000000000000000000000000000000..454e0c263ace003e528ef6c679a694e1c0f41173
--- /dev/null
+++ b/accounts/migrations/0001_initial.py
@@ -0,0 +1,39 @@
+# -*- coding: utf-8 -*-
+# Generated by Django 1.11.24 on 2019-11-13 06:19
+from __future__ import unicode_literals
+
+from django.db import migrations, models
+
+
+class Migration(migrations.Migration):
+
+    initial = True
+
+    dependencies = [
+        ('auth', '0008_alter_user_username_max_length'),
+    ]
+
+    operations = [
+        migrations.CreateModel(
+            name='ListUser',
+            fields=[
+                ('password', models.CharField(max_length=128, verbose_name='password')),
+                ('last_login', models.DateTimeField(blank=True, null=True, verbose_name='last login')),
+                ('is_superuser', models.BooleanField(default=False, help_text='Designates that this user has all permissions without explicitly assigning them.', verbose_name='superuser status')),
+                ('email', models.EmailField(max_length=254, primary_key=True, serialize=False)),
+                ('groups', models.ManyToManyField(blank=True, help_text='The groups this user belongs to. A user will get all permissions granted to each of their groups.', related_name='user_set', related_query_name='user', to='auth.Group', verbose_name='groups')),
+                ('user_permissions', models.ManyToManyField(blank=True, help_text='Specific permissions for this user.', related_name='user_set', related_query_name='user', to='auth.Permission', verbose_name='user permissions')),
+            ],
+            options={
+                'abstract': False,
+            },
+        ),
+        migrations.CreateModel(
+            name='Token',
+            fields=[
+                ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
+                ('email', models.EmailField(max_length=254)),
+                ('uid', models.CharField(max_length=255)),
+            ],
+        ),
+    ]
diff --git a/accounts/migrations/__init__.py b/accounts/migrations/__init__.py
new file mode 100644
index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391
diff --git a/accounts/models.py b/accounts/models.py
new file mode 100644
index 0000000000000000000000000000000000000000..b914dbe4fc334e94194cfd1d1e99379dcaa42be6
--- /dev/null
+++ b/accounts/models.py
@@ -0,0 +1,32 @@
+from django.db import models
+from django.contrib.auth.models import (
+    AbstractBaseUser, BaseUserManager, PermissionsMixin
+)
+
+# Create your models here.
+class Token(models.Model):
+    email = models.EmailField()
+    uid = models.CharField(max_length=255)
+
+class ListUserManager(BaseUserManager):
+
+    def create_user(self, email):
+        ListUser.objects.create(email=email)
+
+    def create_superuser(self, email, password):
+        self.create_user(email)
+
+class ListUser(AbstractBaseUser, PermissionsMixin):
+    email = models.EmailField(primary_key=True)
+    USERNAME_FIELD = 'email'
+    #REQUIRED_FIELDS = ['email', 'height']
+
+    objects = ListUserManager()
+
+    @property
+    def is_staff(self):
+        return self.email == 'harry.percival@example.com'
+
+    @property
+    def is_active(self):
+        return True
diff --git a/accounts/templates/login_email_sent.html b/accounts/templates/login_email_sent.html
new file mode 100644
index 0000000000000000000000000000000000000000..2aa6e4ffd35016363271165018e8bbc5dfa387f9
--- /dev/null
+++ b/accounts/templates/login_email_sent.html
@@ -0,0 +1,7 @@
+<html>
+<h1>Email sent</h1>
+
+<p>Check your email, you'll find a message with a link that will log you into
+the site.</p>
+
+</html>
\ No newline at end of file
diff --git a/accounts/tests.py b/accounts/tests.py
new file mode 100644
index 0000000000000000000000000000000000000000..7ce503c2dd97ba78597f6ff6e4393132753573f6
--- /dev/null
+++ b/accounts/tests.py
@@ -0,0 +1,3 @@
+from django.test import TestCase
+
+# Create your tests here.
diff --git a/accounts/urls.py b/accounts/urls.py
new file mode 100644
index 0000000000000000000000000000000000000000..10f0e241ced16c3e23ac731cc40a705c2d33ec0d
--- /dev/null
+++ b/accounts/urls.py
@@ -0,0 +1,8 @@
+from django.conf.urls import url
+from accounts import views
+
+urlpatterns = [
+    url(r'^send_email$', views.send_login_email, name='send_login_email'),
+    url(r'^login$', views.login, name='login'),
+    url(r'^logout$', views.logout, name='logout'),
+]
\ No newline at end of file
diff --git a/accounts/views.py b/accounts/views.py
new file mode 100644
index 0000000000000000000000000000000000000000..53ad020113fdaef69fef2eda931028e4fea5adc4
--- /dev/null
+++ b/accounts/views.py
@@ -0,0 +1,35 @@
+import uuid
+import sys
+from django.contrib.auth import authenticate
+from django.contrib.auth import login as auth_login, logout as auth_logout
+from django.core.mail import send_mail
+from django.shortcuts import redirect, render
+
+from accounts.models import Token
+
+
+def send_login_email(request):
+    email = request.POST['email']
+    uid = str(uuid.uuid4())
+    Token.objects.create(email=email, uid=uid)
+    print('saving uid', uid, 'for email', email, file=sys.stderr)
+    url = request.build_absolute_uri(f'/accounts/login?uid={uid}')
+    send_mail(
+        'Your login link for Superlists',
+        f'Use this link to log in:\n\n{url}',
+        'noreply@superlists',
+        [email],
+    )
+    return render(request, 'login_email_sent.html')
+
+def login(request):
+    print('login view', file=sys.stderr)
+    uid = request.GET.get('uid')
+    user = authenticate(uid=uid)
+    if user is not None:
+        auth_login(request, user)
+    return redirect('/')
+
+def logout(request):
+    auth_logout(request)
+    return redirect('/')
diff --git a/lists/templates/base.html b/lists/templates/base.html
index 87296be4577ebcb191e90f8b0df58d07aeb5111d..0cc48a47ce717185a6d020f97f082bb2126a575a 100644
--- a/lists/templates/base.html
+++ b/lists/templates/base.html
@@ -12,6 +12,19 @@
 
     <body>
         <div class="container">
+
+                <div class="navbar">
+                        {% if user.is_authenticated %}
+                          <p>Logged in as {{ user.email }}</p>
+                          <p><a id="id_logout" href="{% url 'logout' %}">Log out</a></p>
+                        {% else %}
+                          <form method="POST" action ="{% url 'send_login_email' %}">
+                            Enter email to log in: <input name="email" type="text" />
+                            {% csrf_token %}
+                          </form>
+                        {% endif %}
+                      </div>
+                      
             <div class="row">
                 <div class="col-md-6 col-md-offset-3">
                     <div class="text-center">
diff --git a/superlists/settings.py b/superlists/settings.py
index 736f5e2bdea8631b1b618b3926d1b154fc9e345d..8a90a128bcfb9ab2d9ecacfab7d370015624a68a 100644
--- a/superlists/settings.py
+++ b/superlists/settings.py
@@ -40,8 +40,15 @@ INSTALLED_APPS = [
     'django.contrib.staticfiles',
     'django_mutpy',
     'lists',
+    'accounts'
 ]
 
+AUTH_USER_MODEL = 'accounts.ListUser'
+AUTHENTICATION_BACKENDS = [
+    'accounts.authentication.PasswordlessAuthenticationBackend',
+]
+
+
 MIDDLEWARE = [
     'django.middleware.security.SecurityMiddleware',
     'django.contrib.sessions.middleware.SessionMiddleware',
@@ -131,3 +138,8 @@ if 'DATABASE_URL' in os.environ:
     DATABASES = {'default': dj_database_url.config()}
 
 
+EMAIL_HOST = 'smtp.gmail.com'
+EMAIL_HOST_USER = 'arlonsy82@gmail.com'
+EMAIL_HOST_PASSWORD = os.environ.get('EMAIL_PASSWORD')
+EMAIL_PORT = 587
+EMAIL_USE_TLS = True
\ No newline at end of file
diff --git a/superlists/urls.py b/superlists/urls.py
index 9eae9c58e27022b1995b17806a233689175b86fe..802692a4e9de56c897f3b392f61290741b00061a 100644
--- a/superlists/urls.py
+++ b/superlists/urls.py
@@ -15,9 +15,11 @@ Including another URLconf
 """
 from django.conf.urls import include, url
 from lists import views as list_views  
-from lists import urls as list_urls  
+from lists import urls as list_urls
+from accounts import urls as accounts_urls
 
 urlpatterns = [
     url(r'^$', list_views.home_page, name='home'),
     url(r'^lists/', include(list_urls)), 
+    url(r'^accounts/', include(accounts_urls)),
 ]