Ответ 1
Вот мое решение. Он использует не COOKIES, а пользовательский Auth Backend.
Шаг 1
Для этого полезно иметь приложение Django:
key_auth/
templates/
key_auth_form.html # very simple form template
__init__.py
models.py
urls.py
views.py
forms.py
middleware.py
backend.py
settings.py:
INSTALLED_APPS = (
# ...
'key_auth',
)
Шаг 2
Нам нужна Модель для хранения ваших токенов. models.py:
from django.db import models
from django.contrib.auth.models import User
class SecurityKey(models.Model):
key = models.CharField(max_length=32, unique=True)
user = models.OneToOneField(User)
Примечание. В моем простом решении вам потребуется создать и синхронизировать новых пользователей и их SecurityKeys вручную. Но вы можете улучшить это в будущем.
Шаг 3
Нам нужно специальное промежуточное программное обеспечение, которое потребует аутентификации у всех пользователей на всех страницах (за исключением нескольких специальных страниц). Вот middleware.py:
from django.contrib.auth.decorators import login_required
from django.core.urlresolvers import reverse
class KeyAuthMiddleware(object):
def process_view(self, request, view_func, view_args, view_kwargs):
login_url = reverse('key_auth_login') # your custom named view
# Exceptional pages
login_page = request.path.find(login_url) == 0
logout_page = request.path.find(reverse('logout')) == 0
admin_page = request.path.find(reverse('admin:index')) == 0 # I've excluded Admin Site urls
if not login_page and not logout_page and not admin_page:
view_func = login_required(view_func, login_url=login_url)
return view_func(request, *view_args, **view_kwargs)
Это промежуточное программное обеспечение перенаправляет неавторизованных пользователей на страницу "key_auth_login" с формой auth.
Шаг 4
Вот urls.py, который отображает "key_auth_login":
from django.conf.urls.defaults import patterns, url
urlpatterns = patterns('key_auth.views',
url(r'^$', 'login_view', name='key_auth_login'),
)
И глобальный проект urls.py:
from django.contrib import admin
from django.conf.urls.defaults import patterns, include, url
admin.autodiscover()
urlpatterns = patterns('',
url(r'^key_auth/$', include('key_auth.urls')),
url(r'^logout/$', 'django.contrib.auth.views.logout', {'next_page': '/'}, name='logout'),
url(r'^admin/', include(admin.site.urls)),
url(r'^$', 'views.home_page'),
)
Как вы можете видеть - Admin Site включен (так что вы также можете войти в систему как admin).
Шаг 5
Вот наш взгляд (views.py):
from django.contrib.auth import login
from django.views.generic.edit import FormView
from key_auth.forms import KeyAuthenticationForm
class KeyAuthLoginView(FormView):
form_class = KeyAuthenticationForm
template_name = 'key_auth_form.html'
def form_valid(self, form):
login(self.request, form.user)
return super(KeyAuthLoginView, self).form_valid(form)
def get_success_url(self):
return self.request.REQUEST.get('next', '/')
login_view = KeyAuthLoginView.as_view()
Я не буду показывать 'key_auth_form.html', потому что это действительно простой шаблон формы, ничего особенного. Но я покажу класс формы
Шаг 6
Класс формы (forms.py):
from django import forms
from django.contrib.auth import authenticate
class KeyAuthenticationForm(forms.Form):
key = forms.CharField('Key', help_text='Enter your invite/authorization security key')
user = None
def clean_key(self):
key = self.cleaned_data['key']
self.user = authenticate(key=key)
if not self.user:
raise forms.ValidationError('Please, enter valid security key!')
return key
Как мы видим, authenticate() используется здесь. Этот метод попытается аутентифицировать пользователя с существующими бэкэндами.
Шаг 7
Пользовательский сервер аутентификации. backend.py:
from django.contrib.auth.models import User
from key_auth.models import SecurityKey
class KeyAuthBackend(object):
def authenticate(self, key=None):
try:
return SecurityKey.objects.get(key=key).user
except SecurityKey.DoesNotExist:
return None
def get_user(self, user_id):
try:
return User.objects.get(pk=user_id)
except User.DoesNotExist:
return None
Это очень просто! Просто проверьте ключ (токен). Вот установка (settings.py):
AUTHENTICATION_BACKENDS = (
'key_auth.backends.KeyAuthBackend',
'django.contrib.auth.backends.ModelBackend',
)
Вторым остается оставить работу администратора сайта.
Резюме
Что это!
- Любой запрос проходит через KeyAuthMiddleware
- KeyAuthMiddleware пропускает логин, выход из системы и URL-адреса администратора...
- ... и перенаправляет всех неавторизованных пользователей на страницу входа в токен-авторизацию (с формой входа в токен)
- Эта форма проверяет "ключ" через метод django.contrib.auth.authenticate()...
- ... который пытается аутентифицировать пользователя через пользовательский бэкэнд аутентификации KeyAuthBackend
- Если auth является успешным и форма действительна, тогда пользовательский KeyAuthLoginView делает django.contrib.auth.login(пользователь) и перенаправляет на запрошенную страницу
Вы также можете использовать Admin Site и логин/выход из режима без key_auth ckeck.