http://www.django-rest-framework.org/
Ich wollte ein Token ausstellen, als ich mich zum ersten Mal mit einer Benutzer-ID und einem Kennwort authentifizierte, und dieses Token dann in die Anforderung aufnehmen. Deshalb habe ich es wie folgt implementiert (verwenden Sie die Django-Benutzertabelle so wie sie ist). ..
Bei der Registrierung von Benutzerinformationen in der Benutzertabelle wird nur das Kennwort mithilfe der Django-Bibliothek gehasht und registriert. https://docs.djangoproject.com/en/1.8/_modules/django/contrib/auth/hashers/#make_password
serializers.py
class UserSerializer(serializers.HyperlinkedModelSerializer):
class Meta:
model = User
fields = ('id', 'username', 'password')
write_only_fields = ('password')
read_only_fields = ('id')
def create(self, validated_data):
"""
Registrieren Sie sich nach dem Hashing des Passworts(Django verwenden Standardbibliothek)
"""
password = validated_data.get('password')
validated_data['password'] = make_password(password)
return User.objects.create(**validated_data)
# ......
Ich habe die Token-Authentifizierungsfunktion des Django REST-Frameworks so wie sie ist verwendet. http://www.django-rest-framework.org/api-guide/authentication/
settings.py
INSTALLED_APPS = (
# .......
'rest_framework.authtoken',
)
Fügen Sie einen Prozess zum Erstellen einer Token-Tabelle hinzu
models.py
@receiver(post_save, sender=settings.AUTH_USER_MODEL)
def create_auth_token(sender, instance=None, created=False, **kwargs):
"""
Wenn ein neuer Benutzer erstellt wird, wird TOKEN automatisch ausgegeben.
"""
if created:
Token.objects.create(user=instance)
Mit den obigen Einstellungen wird, wenn ein Benutzer in der Benutzertabelle registriert ist, ein Token ausgegeben und in der Token-Tabelle gespeichert.
Weisen Sie einem beliebigen URI get_auth_token zu und erstellen Sie einen Endpunkt für den Client, um das Token abzurufen.
urls.py
from rest_framework.authtoken import views as auth_views
urlpatterns = patterns('',
url(r'^api-token-auth/', auth_views.obtain_auth_token),
)
Wenn Sie die JSON-Datei mit Benutzername und Kennwort wie unten gezeigt POSTEN, wird das dem Benutzernamen entsprechende Token zurückgegeben.
$ curl -v -H "Accept: application/json" -H "Content-type: application/json" -X POST -d '{"username":"test","password":"111111"}' https://127.0.0.1:8000/api/api-token-auth/
Wenn Sie eine Anforderung vom Client an einen URI senden, für den ein Token erforderlich ist, ist es in Ordnung, wenn Sie das Token wie folgt in die Autorisierung des HTTP-Headers einfügen.
$ curl -X GET http://127.0.0.1:8000/api/example/ -H 'Authorization: Token 9944b09199c62bcf9418ad846dd0e4bbdfc6ee4b'
Wenn es sich um einen normalen Authentifizierungsprozess handelt und Sie settings.py die folgenden Einstellungen hinzufügen, wird der Inhalt des Tokens überprüft und der Authentifizierungsprozess ausgeführt, wenn eine Anforderung eingeht.
settings.py
REST_FRAMEWORK = {
'DEFAULT_AUTHENTICATION_CLASSES': (
'rest_framework.authentication.TokenAuthentication',
)
}
Wenn Sie diese Einstellung vornehmen, wird die Tokenauthentifizierung standardmäßig für alle Anforderungen an URIs durchgeführt. Wenn Sie also die Authentifizierungsmethode für einige URIs ändern möchten, verwenden Sie Ihre eigene Authentifizierung, wie im folgenden Beispiel gezeigt. Sie können eine Klasse definieren, den Authentifizierungsprozess darin schreiben und diese Klasse in der Ansichtsklasse angeben.
Beachten Sie übrigens, dass dem auf dem Client angegebenen Feldnamen des HTTP-Headers automatisch "HTTP_" vorangestellt wird. Es sieht aus wie Djangos Spezifikationen.
authentications.py
class FooAuthentication(authentication.BaseAuthentication):
def authenticate(self, request):
#Bewerten Sie das feste Standardtoken während des POST
if request.method == 'POST':
default_token = request.META.get('HTTP_DEFAULT_TOKEN')
try:
token = System.objects.get(key='HTTP_DEFAULT_TOKEN')
except Token.DoesNotExist:
raise exceptions.AuthenticationFailed('error')
if default_token != token.value:
raise exceptions.AuthenticationFailed('error')
return None
#Wenn Sie etwas anderes als POST ausführen können, bewerten Sie das für jeden registrierten Wert ausgestellte Authentifizierungstoken.
else:
auth_token = request.META.get('HTTP_AUTHORIZATION')
if not auth_token:
raise exceptions.AuthenticationFailed('Authentication token is none')
try:
user = Token.objects.get(key=auth_token.replace('Token ', ''))
except Token.DoesNotExist:
raise exceptions.AuthenticationFailed('error')
return (user.user, None)
view.py
class FooViewSet(viewsets.ModelViewSet):
queryset = Foo.objects.none()
serializer_class = FooSerializer
authentication_classes = (FooAuthentication, )
# .......
Wenn Sie sich dagegen nur mit einigen URIs authentifizieren möchten, sollten Sie TokenAuthentication in authentication_classes der Ansichtsklasse angeben.
Der Testcode verwendete den REST-Framework-API-Client. http://www.django-rest-framework.org/api-guide/testing/ So was.
tests.py
class UserTests(APITestCase):
def setUp(self):
"""
setUp for testing
"""
User.objects.create(username='user1', password='user1')
User.objects.create(username='user2', password='user2')
self.user1 = User.objects.get(username='user1')
self.user2 = User.objects.get(username='user2')
def test_user_list_normal1(self):
"""
user-list: normal pattern
"""
url = reverse('user-list')
expected_data = {
"count": 1,
"next": None,
"previous": None,
"results": [{
"id": 1,
"username": "user1"
}]
}
token = Token.objects.get(user=self.user1).key
#Token für Autorisierung setzen
self.client.credentials(HTTP_AUTHORIZATION='Token ' + token)
response = self.client.get(url, None, format='json')
self.assertEqual(response.status_code, status.HTTP_200_OK)
#Bestätigen Sie, dass json wie erwartet zurückgegeben wird
self.assertEqual(response.data, expected_data)
Recommended Posts