program tip

비밀번호없이 수동으로 사용자 로그인

radiobox 2020. 11. 14. 10:04
반응형

비밀번호없이 수동으로 사용자 로그인


암호 사용 하지 않고 수동 (서버 측 시작) 로그인을 구현하는 가장 좋은 방법을 찾는 데 도움이 되었기를 바랍니다 . 워크 플로를 설명하겠습니다.

  • 사용자 등록
  • 감사합니다! 활성화 링크가있는 이메일이 발송되었습니다. blablabla
  • (이제 계정이 존재하지만 활성화되지 않은 것으로 표시됨)
  • 사용자가 이메일을 열고 링크를 클릭합니다.
  • (계정이 활성화 됨)
  • 감사합니다! 이제 사이트를 사용할 수 있습니다.

제가하려는 것은 사용자가 이메일 링크를 클릭 한 후 로그인하여 웹 사이트를 바로 사용할 수 있도록하는 것입니다.

DB에 암호화되어 있기 때문에 비밀번호를 사용할 수 없습니다. 사용자 지정 인증 백엔드를 작성하는 유일한 옵션입니까?


당신은에 사용자를 로그온 할 때 암호를 입력 할 필요가 없습니다. auth.login기능은 단지 소요 User계정을 사용하도록 설정하면 당신은 아마도 이미 데이터베이스에서 점점 개체를. 그래서 당신은 login.

물론, 사용자가 이미 활성화 된 기존 계정에 대한 링크를 스푸핑하면 자동으로 해당 사용자로 로그인 할 수 없다는 점에 매우 주의 해야합니다 .

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)

... 등

편집 :

흠, authenticate추가되는 추가 속성으로 인해 사용 요구 사항을 인식하지 못했습니다 . 코드를 보면 backend인증 백엔드의 모듈 경로에 해당 하는 속성 만 있습니다. 따라서 위의 로그인 호출 전에 다음을 수행하십시오.

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

Daniel의 대답은 매우 좋습니다.

이를 수행하는 또 다른 방법은 다음과 같이 Custom Authorization 백엔드 https://docs.djangoproject.com/en/1.8/topics/auth/customizing/#writing-an-authentication-backend에 따라 HashModelBackend를 만드는 것입니다 .

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

그런 다음 설정에 설치하십시오.

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

그러면 귀하의 견해는 다음과 같습니다.

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

Django 1.10부터 프로세스가 단순화되었습니다.

Django의 모든 버전에서 사용자가 로그인하려면 앱의 백엔드 중 하나에서 인증 을 받아야합니다 ( AUTHENTICATION_BACKENDS설정에 의해 제어 됨 ).

단순히 로그인을 강제하려는 경우 해당 목록의 첫 번째 백엔드에서 사용자가 인증되었다고 주장 할 수 있습니다.

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)

에 대한 응답 의 대답.

백엔드 작성 방법 :

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

Answer is based on django.contrib.auth.backends.ModelBackend source code. It's actual for django 1.9

And I would rather place custom backend below django's default:

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

because account activation is less possible than login itself. According to https://docs.djangoproject.com/en/1.9/topics/auth/customizing/#specifying-authentication-backends:

The order of AUTHENTICATION_BACKENDS matters, so if the same username and password is valid in multiple backends, Django will stop processing at the first positive match.

Be careful this code will authenticate your users even with incorrect passwords.


You can use ska package, which has password-less login to Django implemented. ska works with authentication tokens and its security is based on SHARED_KEY which should be equal for all parties (servers) involved.

On client side (party that requests a password-less login), you generate a URL and sign it, using ska. Example:

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',
    }
)

Default lifetime of the token is 600 seconds. You can customise that by proving a lifetime argument.

On the server side (site to which users' log in), having in mind that you have installed ska properly, the user is logged in upon visiting the URL if they existed (username match), or otherwise - created. There are 3 callbacks that you can customise in your project's Django settings.

  • USER_GET_CALLBACK (string): Fired if user was successfully fetched from database (existing user).
  • USER_CREATE_CALLBACK (string): Fired right after user has been created (user didn't exist).
  • USER_INFO_CALLBACK (string): Fired upon successful authentication.

See the documentation (http://pythonhosted.org/ska/) for more.

참고URL : https://stackoverflow.com/questions/2787650/manually-logging-in-a-user-without-password

반응형