Domanda

spero che tu possa aiutarmi a capire il modo migliore per attuare un account di accesso manuale (lato server avviato) senza utilizzando la password. Mi spiego meglio il flusso di lavoro:

  • registri utente
  • Grazie! blablabla un'e-mail con un link di attivazione è stato inviato
  • (account ora esiste, ma è contrassegnato come non abilitata)
  • L'utente apre collegamento e-mail, i clic
  • (account è abilitato)
  • Grazie! È ora possibile utilizzare il sito

Quello che sto cercando di fare è accedere l'utente, dopo aver cliccato sul link e-mail, così da poter iniziare a utilizzare il sito subito.

Non riesco a usare la sua password dal momento che è criptato nel DB, è l'unica opzione a scrivere un backend di autenticazione personalizzato?

È stato utile?

Soluzione

Non è necessario una password per accedere un utente. Il funzione auth.login vuole solo un oggetto User, che si è presumibilmente già ricevendo dal database quando si attiva l'account. Così si può passare che direttamente a login.

Naturalmente, avrete bisogno di essere molto attenti che non c'è modo che un utente può falsificare un collegamento a un account già esistente abilitato, che sarebbe poi accedere automaticamente come quell'utente.

from django.contrib.auth import login

def activate_account(request, hash):
    account = get_account_from_hash(hash)
    if not account.is_active:
        account.activate()
        account.save()
        user = account.user
        login(request, user)

... etc.

A cura :

Hmm, non si accorse che l'obbligo di utilizzo authenticate a causa della proprietà in più, aggiunge. Guardando il codice, non fa altro che un attributo backend equivalente al percorso del modulo del backend di autenticazione. Quindi, si può solo fingere - prima che la chiamata di accesso di cui sopra, fare questo:

user.backend = 'django.contrib.auth.backends.ModelBackend'

Altri suggerimenti

La risposta di Daniel è molto buona.

Un altro modo per farlo è quello di creare un HashModelBackend seguendo le backend personalizzato autorizzazione https://docs.djangoproject.com/en/1.8/topics/auth/customizing/#writing-an-authentication-backend in questo modo:

class HashModelBackend(object):
    def authenticate(self, hash=None):
        user = get_user_from_hash(hash)
        return user

    def get_user(self, user_id):
        try:
            return User.objects.get(pk=user_id)
        except User.DoesNotExist:
            return None

E poi installare questo nelle impostazioni:

AUTHENTICATION_BACKENDS = (
    'myproject.backends.HashModelBackend',
    'django.contrib.auth.backends.ModelBackend',
)

Allora la vostra vista sarebbe qualcosa di simile:

def activate_account(request, hash):
    user = authenticate(hash=hash)
    if user:
        # check if user is_active, and any other checks
        login(request, user)
    else:
        return user_not_found_bad_hash_message

Al Django 1.10, il processo è stato semplificato.

In tutte le versioni di Django, in modo che un utente di effettuare il login, devono essere autenticato da uno dei backend della tua app (controllata dalla impostazione AUTHENTICATION_BACKENDS).

Se si vuole semplicemente imporre un login, si può solo affermare che l'utente è stato autenticato dal primo back-end da quella lista:

from django.conf import settings
from django.contrib.auth import login


# Django 1.10+
login(request, user, backend=settings.AUTHENTICATION_BACKENDS[0])

# Django <1.10 -  fake the authenticate() call
user.backend = settings.AUTHENTICATION_BACKENDS[0]
login(request, user)

Risposta a dan 's risposta.

Un modo per scrivere il backend:

from django.contrib.auth import get_user_model
from django.contrib.auth.backends import ModelBackend

class HashModelBackend(ModelBackend):

def authenticate(self, username=None, **kwargs):
    UserModel = get_user_model()
    if username is None:
        username = kwargs.get(UserModel.USERNAME_FIELD)
    try:
        user = UserModel._default_manager.get_by_natural_key(username)
        return user
    except UserModel.DoesNotExist:
        return None

risposta si basa su django.contrib.auth.backends.ModelBackend il codice sorgente. E 'vero per Django 1.9

E avrei preferito luogo personalizzato backend predefinito di sotto di Django:

AUTHENTICATION_BACKENDS = [
    'django.contrib.auth.backends.ModelBackend',
    'yours.HashModelBackend',
]

a causa di attivazione dell'account è minore possibile di effettuare il login per sé. Secondo https://docs.djangoproject.com/ it / 1,9 / argomenti / auth / personalizzazione / # specificando-autenticazione-backend :

  

L'ordine delle cose AUTHENTICATION_BACKENDS, quindi se lo stesso nome utente e password è valida in più backend, Django si fermerà elaborazione al primo riscontro positivo.

Fare attenzione questo codice autenticherà gli utenti anche con password errate.

È possibile utilizzare il pacchetto ska, che ha accesso senza password per Django implementato. ska lavora con i token di autenticazione e la sua sicurezza si basa su SHARED_KEY che dovrebbe essere uguale per tutte le parti coinvolte (server).

Sul lato client (partito che le richieste di accesso senza password), si genera un URL e firmare, usando ska. Esempio:

from ska import sign_url
from ska.contrib.django.ska.settings import SECRET_KEY

server_ska_login_url = 'https://server-url.com/ska/login/'

signed_url = sign_url(
    auth_user='test_ska_user_0',
    secret_key=SECRET_KEY,
    url=server_ska_login_url
    extra={
        'email': 'john.doe@mail.example.com',
        'first_name': 'John',
        'last_name': 'Doe',
    }
)

durata predefinita del token è di 600 secondi. È possibile personalizzare che dimostrando un argomento lifetime.

Sul lato server (sito a cui registro degli utenti a), tenendo presente che è stato installato ska correttamente, l'utente viene registrato nel momento visitando l'URL se esistessero (partita username), o in altro modo - creati. Ci sono 3 callback che è possibile personalizzare le impostazioni di Django del vostro progetto.

  • USER_GET_CALLBACK (stringa):. Licenziato se l'utente fosse successo prelevato dalla banca dati (utente esistente)
  • USER_CREATE_CALLBACK (stringa):. Fired subito dopo utente è stato creato (l'utente non esisteva)
  • USER_INFO_CALLBACK (stringa):. Fired su l'autenticazione

Per ulteriori consultare la documentazione ( http://pythonhosted.org/ska/ ).

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top