パスワードなしでユーザーに手動でログインします
-
03-10-2019 - |
質問
マニュアル(サーバー側の開始)ログインを実装する最良の方法を把握できることを願っています それなし パスワードを使用します。ワークフローについて説明させてください:
- ユーザーレジスタ
- ありがとうございました!アクティベーションリンクがあるメールが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'
他のヒント
ダニエルの答えはとても良いです。
それを行う別の方法は、カスタム認証バックエンドに続いてハッシュモデルバックエンドを作成することです https://docs.djangoproject.com/en/1.8/topics/auth/customizing/#writing-an-authentication-backend このような:
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のすべてのバージョンで、ユーザーがログインするためには、 アプリのバックエンドの1つによって認証されます (によって制御されます 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
答えはに基づいています django.contrib.auth.backends.modelbackend ソースコード。 Django 1.9の場合は実際です
そして、私はむしろカスタムバックエンドをDjangoのデフォルトの下に置きたいです。
AUTHENTICATION_BACKENDS = [
'django.contrib.auth.backends.ModelBackend',
'yours.HashModelBackend',
]
アカウントのアクティブ化はログイン自体よりも少ないためです。によると https://docs.djangoproject.com/en/1.9/topics/auth/customizing/#specificiance-authentication-backends:
authentication_backendsの順序が重要であるため、同じユーザー名とパスワードが複数のバックエンドで有効な場合、Djangoは最初のポジティブマッチで処理を停止します。
気をつけてこのコードは、パスワードが誤っていてもユーザーに認証されます。
使用できます ska
パスワードレスのDjangoへのログインが実装されているパッケージ。 ska
認証トークンを使用して動作し、そのセキュリティは、関与するすべての関係者(サーバー)に等しいはずです。
クライアント側(パスワードレスログインを要求するパーティ)で、URLを生成して署名して、 ska
. 。例:
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',
}
)
トークンのデフォルトの寿命は600秒です。あなたはそれを証明することによってカスタマイズできます lifetime
口論。
サーバー側(ユーザーがログインするサイト)で、インストールしたことを念頭に置いて ska
適切に、ユーザーが存在する場合(ユーザー名マッチ)、または作成された場合、URLにアクセスするとログインします。プロジェクトのDjango設定でカスタマイズできる3つのコールバックがあります。
USER_GET_CALLBACK
(文字列):ユーザーがデータベース(既存のユーザー)から正常にフェッチされた場合に起動します。USER_CREATE_CALLBACK
(文字列):ユーザーが作成された直後に解雇されました(ユーザーは存在しませんでした)。USER_INFO_CALLBACK
(文字列):認証が成功したときに発射されます。
ドキュメントを参照してください(http://pythonhosted.org/ska/) 多くのための。