コンテンツにスキップ

Python

パッケージ: tenon-auth 1.0.0(Python 3.9 以降)。

  • 依存関係: 標準ライブラリのみ。
  • 型: 型情報つきです(py.typed)。
  • スレッド: クライアントはスレッドセーフなので、プロセスごとに1つ作ってください。

ダウンロードから wheel を取得し、SHA-256 を確認してインストールします:

ターミナルウィンドウ
pip install tenon_auth-1.0.0-py3-none-any.whl
import os
from tenon_auth import TenonAuthClient
tenon_auth = TenonAuthClient(os.environ["TENON_AUTH_URL"], os.environ["TENON_AUTH_API_KEY"])

オプション:

  • timeout(30秒)
  • headers
  • ssl_context(社内 CA 用)

プロキシは HTTPS_PROXY から設定されます。キーが別の場所に送られないよう、リダイレクトは決してたどりません。

from tenon_auth import SecondStep, SignInContext, TenonAuthUnavailableError
@app.post("/login")
def login():
account = check_password(request.form["username"], request.form["password"]) # あなたの処理
try:
step = tenon_auth.begin_second_step(
str(account.id),
SignInContext(request.remote_addr, request.headers.get("User-Agent")), # remote_addr には ProxyFix
trusted_device_token=request.cookies.get("tenon_device"),
)
except TenonAuthUnavailableError:
return emergency_or_refuse(account) # フェイルクローズ
session["second_step"] = step.to_dict() # サーバー側のセッション(Flask-Session)を使ってください
if step.kind == "CODE_ENTRY":
return redirect("/login/code")
if step.kind == "PUSH_WAIT":
return redirect("/login/approve")
if step.kind == "RECOVERY_ONLY":
return redirect("/login/recover")
return sign_in(account) # TRUSTED または NO_METHOD
@app.post("/login/code")
def code():
step = SecondStep.from_dict(session["second_step"])
result = tenon_auth.complete_with_code(step, request.form["code"])
if result.approved:
return sign_in_user(step.user_id)
if result.status == "WRONG_CODE":
return redirect(f"/login/code?left={result.attempts_remaining}")
return redirect("/login") # FAILED、EXPIRED

ほかの画面:

  • 待機画面では、2秒ごとに tenon_auth.poll_approval(step) を呼びます。
  • リカバリー画面では、tenon_auth.complete_with_recovery_code(step, code) を呼びます。

Django: ビューで同じ呼び出しを request.session とともに使います。クライアントは settings で1回だけ作ってください。

すべて TenonAuthError のサブクラスです:

  • TenonAuthUnavailableError(reason)
  • ApiKeyRejectedError、ForbiddenError
  • InvalidRequestError、NotFoundError、InvalidCodeError
  • FactorLockedError、TooManyRequestsError
  • EmailRefusedError、EmailUnavailableError
  • ConflictError

エラーを参照してください。