http://www.django-rest-framework.org/
Je voulais émettre un jeton lorsque je me suis authentifié pour la première fois avec un ID utilisateur et un mot de passe, puis inclure ce jeton dans la demande, donc je l'ai implémenté comme suit (utilisez la table des utilisateurs Django telle quelle) ..
Lors de l'enregistrement des informations utilisateur dans la table User, seul le mot de passe est haché à l'aide de la bibliothèque Django et enregistré. 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):
"""
S'inscrire après le hachage du mot de passe(django utilise la bibliothèque par défaut)
"""
password = validated_data.get('password')
validated_data['password'] = make_password(password)
return User.objects.create(**validated_data)
# ......
J'ai utilisé la fonction d'authentification par jeton du framework Django REST tel quel. http://www.django-rest-framework.org/api-guide/authentication/
settings.py
INSTALLED_APPS = (
# .......
'rest_framework.authtoken',
)
Ajouter un processus pour créer une table de jetons
models.py
@receiver(post_save, sender=settings.AUTH_USER_MODEL)
def create_auth_token(sender, instance=None, created=False, **kwargs):
"""
Lorsqu'un nouvel utilisateur est créé, TOKEN est automatiquement émis.
"""
if created:
Token.objects.create(user=instance)
Avec les paramètres ci-dessus, lorsqu'un utilisateur est enregistré dans la table User, un jeton est émis et stocké dans la table Token.
Attribuez gets_auth_token à n'importe quel URI et créez un point de terminaison pour que le client obtienne le jeton.
urls.py
from rest_framework.authtoken import views as auth_views
urlpatterns = patterns('',
url(r'^api-token-auth/', auth_views.obtain_auth_token),
)
Si vous POSTEZ le fichier json contenant le nom d'utilisateur et le mot de passe comme indiqué ci-dessous, le jeton correspondant au nom d'utilisateur sera retourné.
$ 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/
Lors de l'envoi d'une demande du client à un URI qui nécessite un jeton, il est OK si vous placez le jeton dans l'autorisation de l'en-tête HTTP comme suit.
$ curl -X GET http://127.0.0.1:8000/api/example/ -H 'Authorization: Token 9944b09199c62bcf9418ad846dd0e4bbdfc6ee4b'
S'il s'agit d'un processus d'authentification normal, si vous ajoutez les paramètres suivants à settings.py, il vérifiera le contenu du jeton et effectuera le processus d'authentification lorsqu'une demande arrive.
settings.py
REST_FRAMEWORK = {
'DEFAULT_AUTHENTICATION_CLASSES': (
'rest_framework.authentication.TokenAuthentication',
)
}
Cependant, si vous définissez ce paramètre, l'authentification par jeton sera effectuée par défaut pour les demandes adressées à tous les URI, donc si vous souhaitez modifier la méthode d'authentification pour certains URI, utilisez votre propre authentification, comme indiqué dans l'exemple ci-dessous. Vous pouvez définir une classe, y écrire le processus d'authentification et spécifier cette classe dans la classe de vue.
En passant, notez que le nom du champ Http Header spécifié sur le client est automatiquement préfixé par "HTTP_". Cela ressemble aux spécifications de Django.
authentications.py
class FooAuthentication(authentication.BaseAuthentication):
def authenticate(self, request):
#Évaluer le jeton fixe par défaut lors du 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
#Si vous pouvez faire autre chose que POST, évaluez le jeton d'authentification émis pour chaque valeur enregistrée.
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, )
# .......
Au contraire, si vous souhaitez vous authentifier uniquement avec certains URI, vous devez spécifier TokenAuthentication dans authentication_classes de la classe d'affichage.
Le code de test a utilisé le client API du framework REST. http://www.django-rest-framework.org/api-guide/testing/ Comme ça.
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
#Définir le jeton pour l'autorisation
self.client.credentials(HTTP_AUTHORIZATION='Token ' + token)
response = self.client.get(url, None, format='json')
self.assertEqual(response.status_code, status.HTTP_200_OK)
#Confirmez que json est renvoyé comme prévu
self.assertEqual(response.data, expected_data)
Recommended Posts