Django-rest-framework: TokenAuthentication -- Pourquoi ne peut-il y avoir qu'un seul jeton par utilisateur ?

Créé le 20 janv. 2013  ·  24Commentaires  ·  Source: encode/django-rest-framework

dans authtoken/models.py l'association User <-> Token est un OneToOneField. Y a-t-il une raison particulière pour qu'il ne s'agisse pas d'une simple clé étrangère ?

Avec les sessions, les utilisateurs peuvent avoir plusieurs sessions ouvertes. Avec les API, les gens peuvent avoir plusieurs appareils / applications qui parlent à un service et il serait préférable qu'ils ne partagent pas le même jeton.

Il est très simple d'écrire une TokenAuthentication personnalisée qui autorise plusieurs jetons (j'ai besoin de quelque chose de similaire à l'API de GitHub, avec une note / note_url associée à chaque jeton) mais je me demande si ce ne serait pas une valeur par défaut plus raisonnable d'autoriser plusieurs jetons par utilisateur. Je suis heureux d'écrire un correctif pour cela, sinon je vais simplement lancer mon propre TokenAuthentication.

Des avis?

Commentaire le plus utile

Je trouve la comparaison jeton = mot de passe idiote. Connaissez-vous des services qui vous obligent à changer votre mot de passe et à invalider toutes les autres sessions que vous avez ouvertes à chaque fois que vous vous déconnectez ?

Tous les 24 commentaires

imaginez que le jeton ressemble à un mot de passe. c'est quelque chose qui vous authentifie contre le système. avez-vous un service avec plus d'un mot de passe associé à votre compte ? je suppose que non ;)

@brutasse - Les deux options sont raisonnables, pour des raisons différentes. Je pense que nous avons commencé avec FK, puis nous nous sommes retrouvés avec 1-1 à la fin car il existe une vue qui obtient ou crée pour le jeton d'authentification d'un utilisateur, et il n'est pas évident de savoir quel devrait être le comportement s'il y a plusieurs jetons.

Une option serait que si vous décidiez de packager votre implémentation d'authentification de jeton sur PyPI, nous pourrions alors y accéder à partir de la documentation comme alternative, ce qui serait formidable. Je recommanderais ceci : https://github.com/dabapps/django-reusable-app pour obtenir rapidement quelque chose sur PyPI si vous voulez le faire.

@tomchristie -- merci, je vais probablement finir par faire ça. Je vous dirai si/quand j'aurai quelque chose.

@brutasse Ce serait un as - merci !

J'ai trouvé cette limitation déroutante compte tenu de la doc :

This authentication scheme uses a simple token-based HTTP Authentication scheme. Token authentication is appropriate for client-server setups, such as native desktop and mobile clients.

Je pense surtout que lorsque cette fonctionnalité est utilisée pour les clients mobiles, les utilisateurs uniques auraient plus d'un jeton, un pour chaque appareil à partir duquel ils accèdent.

@brutasse Il y a déjà un truc comme ça ?

Le package d'authentification JWT tiers est la meilleure implémentation alternative d'authentification de jeton. Cela vaut la peine d'être regardé.

+1

Je trouve la comparaison jeton = mot de passe idiote. Connaissez-vous des services qui vous obligent à changer votre mot de passe et à invalider toutes les autres sessions que vous avez ouvertes à chaque fois que vous vous déconnectez ?

@jonathan-golorry :+1: Exactement ! Il ne doit y avoir aucune relation/comparaison entre le jeton et le mot de passe.

Le mot de passe eq du jeton de comparaison est une incompréhension totale. Jetons par définition un mécanisme d'authentification à court terme, et le mot de passe ne l'est pas. Avoir plusieurs jetons par utilisateur n'est pas du tout une mauvaise idée.

Les gars, existe-t-il un mécanisme d'autorisation de jeton tiers qui produira des jetons par client mobile ? (appareil mobile) ?

@rwoloszyn Oui, vous voudrez peut-être consulter Django OAuth Toolkit . Je l'utilise via Django REST framwork Social OAuth2 pour les cas d'utilisation sociaux et non sociaux.

@JockeTF merci. Je vais y jeter un coup d'œil, mais pour autant que je vérifie maintenant, je peux trouver quelque chose sur la génération de plusieurs jetons par appareil.

Ah, j'interprétais...

Les gars, existe-t-il un mécanisme d'autorisation de jeton tiers qui produira des jetons par client mobile ? (appareil mobile) ?

... Comme il existe plusieurs _types_ de clients pour lesquels les utilisateurs doivent avoir des jetons différents.

Avec la bibliothèque OAuth, les utilisateurs obtiendront un nouveau jeton d'accès et d'actualisation à chaque fois qu'ils soumettront leur nom d'utilisateur et leur mot de passe. Les jetons seront liés à un identifiant client spécifique (application). Chaque utilisateur peut avoir plusieurs tokens valides pour plusieurs clients différents au même moment. Les jetons d'accès sont généralement de courte durée, mais de nouveaux peuvent être récupérés à l'aide du jeton d'actualisation.

@JockeTF d' accord. Je comprends. Mais je veux accomplir autre chose.
Je voudrais permettre à l'utilisateur de se connecter/s'inscrire par facebook et pour l'instant uniquement facebook et une fois la connexion ou l'inscription terminée, générer mon propre jeton backend qui sera utilisé entre le client<-> backend
la communication. J'aimerais également avoir différents jetons pour différents clients mobiles.
Ex. L'utilisateur a 2 téléphones portables. Je souhaite générer un jeton par client et associer également des jetons à cet appareil spécifique. Ainsi, lors de la prochaine connexion de l'utilisateur, je saurai quel appareil il utilise.
Je ne veux pas que l'utilisateur fournisse un nom d'utilisateur/mot de passe personnel. Je souhaite m'authentifier avec faceboook, récupérer mon jeton backend unique par appareil. Existe-t-il une solution prête à l'emploi qui pourrait le faire ? Sinon je vais en faire un :)

@rwoloszyn Django REST framwork Social OAuth2 fera la plupart de ce que vous voulez Python Social Auth , en particulier sur la façon de personnaliser le pipeline.

Je ne sais pas si l'utilisation de différents identifiants de clients pour les différents appareils a du sens dans votre cas, vous devriez donc vous renseigner. Si vous ne souhaitez pas utiliser un identifiant client différent par appareil, vous devrez créer quelque chose pour garder une trace de l'appareil auquel appartiennent les jetons. Cependant, les choses fonctionnent à peu près comme vous le souhaitez si vous utilisez un ID client unique par appareil.

@JockeTF qui semble vraiment bien. Merci pour les bons conseils. Je partagerai mes résultats dès que cela fonctionnera. Merci encore.

Paquet associé :

L'authentification Knox est basée sur des jetons, similaire à
TokenAuthentication intégré au DRF. Cependant, il surmonte certains
problèmes présents dans l'implémentation par défaut :

  • Les jetons DRF sont générés avec os.urandom , ce qui n'est pas
    cryptographiquement sécurisé.

Knox utilise OpenSSL pour fournir des jetons.

  • Les jetons DRF sont limités à un par utilisateur. Cela ne facilite pas
    connexion sécurisée à partir de plusieurs appareils, car le jeton est partagé. Ce
    nécessite également la déconnexion de _tous_ les appareils si une déconnexion côté serveur
    est requis (c'est-à-dire que le jeton est supprimé).

Knox fournit un jeton par appel à la vue de connexion - permettant à chaque
client d'avoir son propre jeton qui est supprimé côté serveur lorsque
le client se déconnecte.

Knox fournit également une option permettant à un client connecté de supprimer _all_
jetons que le serveur possède - forçant tous les clients à se ré-authentifier.

  • Les jetons DRF sont stockés non cryptés dans la base de données. Cela permettrait
    un attaquant un accès illimité à un compte avec un token si le
    base de données ont été compromises.

Les jetons Knox ne sont stockés que sous une forme cryptée. Même si le
base de données ont été volés, un attaquant ne serait pas en mesure de se connecter
avec les identifiants volés.

  • Les jetons DRF suivent leur temps de création, mais n'ont pas de mécanisme intégré pour les jetons
    expirant. Les jetons Knox peuvent avoir une expiration configurée dans les paramètres de l'application (la valeur par défaut est
    10 heures.)

@brutasse Cela fait plus de trois ans, existe-t-il une solution pour résoudre ce problème, merci de me le faire savoir, merci !!!

@thisismsreddy rien de directement utilisable mais vous pouvez consulter https://github.com/feedhq/feedhq/blob/master/feedhq/reader/models.py -- plusieurs jetons par utilisateur, stockés dans la base de données avec des recherches de cache pour accélérer les choses et épargner les requêtes SQL.

pourquoi ne pas utiliser FK ici https://github.com/encode/django-rest-framework/blob/master/rest_framework/authtoken/models.py#L16 ? Alors ça permet plus d'une session par utilisateur ? Bien sûr, il faut alors plus de modifications à d'autres choses comme des exemples aussi. Penser à la façon dont le nouveau jeton doit être créé, comme si nous utilisions get_or_create, cela ne crée pas de nouveau jeton. Au lieu de cela, il utilisera le comportement actuel.

Quoi qu'il en soit, il n'est pas difficile de remplacer la fonction get_model de TokenAuthentication https://github.com/encode/django-rest-framework/blob/master/rest_framework/authentication.py#L160 et d'utiliser un modèle différent là-bas.

5 ans plus tard, et c'est toujours un problème. La plupart des produits/services nécessitent plusieurs sessions par utilisateur. Imaginez que vous vous connectez à votre compte depuis l'application Web et que votre téléphone vous informe que vous êtes déconnecté de l'application mobile. Corrigez-le en vous reconnectant sur le téléphone pour découvrir que vous êtes déconnecté de l'application Web, _ad infinitum_.

vous connecter à votre compte depuis l'application Web et votre téléphone vous avertit que vous êtes déconnecté

Cela ne devrait pas être le cas. Vous êtes censé utiliser le même jeton pour chaque appareil, ne pas révoquer le jeton de l'ancien appareil et créer un nouveau jeton pour le nouvel appareil. La seule fois où cela pose un problème, c'est si vous souhaitez spécifiquement mettre fin à la session d'un seul appareil. Disons que vous utilisez un ordinateur public et que vous vous déconnectez. Si la déconnexion révoque le jeton, tous les appareils sont déconnectés. Si la déconnexion ne révoque pas le token, alors toute personne qui a volé votre token a désormais un accès

Je pourrais voir votre boucle de connexion/déconnexion si vous utilisiez d'une manière ou d'une autre la rotation des jetons, mais à ce stade, vous utilisez déjà un package tiers pour les jetons.

oauth2 serait-il une solution ? Pas d'état de session en soi, juste des jetons porteurs.

Le dimanche 21 octobre 2018 à 17h42 Rahul Soibam [email protected]
a écrit:

5 ans plus tard, et c'est toujours un problème. La plupart des produits/services nécessitent
plusieurs sessions par utilisateur. Imaginez que vous vous connectez à votre compte depuis le Web
l'application et votre téléphone vous avertit que vous êtes déconnecté du mobile
application. Corrigez-le en vous reconnectant au téléphone pour découvrir que vous êtes
déconnecté de l'application Web à l'infini.

-
Vous recevez ceci parce que vous êtes abonné à ce fil.
Répondez directement à cet e-mail, consultez-le sur GitHub
https://github.com/encode/django-rest-framework/issues/601#issuecomment-431706649 ,
ou couper le fil
https://github.com/notifications/unsubscribe-auth/AEJ5dzQy2VU-qvvRUaW14cpuvOv5Bv2Tks5unOosgaJpZM4AX2yZ
.

Cette page vous a été utile?
0 / 5 - 0 notes