Skip to main content

Python

配置Authok

获取应用密钥

你需要如下信息

  • Domain
  • Client ID
  • Client Secret

配置回调URL

配置 Logout URL

安装依赖

在工程目录创建requirements.txt文件:

📁requirements.txt
flask>=2.0.3
python-dotenv>=0.19.2
authlib>=1.0
requests>=2.27.1

配置.env文件

在工程目录创建.env文件:

.env
AUTHOK_CLIENT_ID=YOUR_CLIENT_ID
AUTHOK_CLIENT_SECRET=YOUR_CLIENT_SECRET
AUTHOK_DOMAIN=YOUR_DOMAIN
APP_SECRET_KEY=

设置应用

server.py
import json
from os import environ as env
from urllib.parse import quote_plus, urlencode

from authlib.integrations.flask_client import OAuth
from dotenv import find_dotenv, load_dotenv
from flask import Flask, redirect, render_template, session, url_for

加载.env文件:

# 追加到 server.py 文件

ENV_FILE = find_dotenv()
if ENV_FILE:
load_dotenv(ENV_FILE)

配置 Flask:

# 追加到 server.py 文件

app = Flask(__name__)
app.secret_key = env.get("APP_SECRET_KEY")

配置 Authlib 以使用 AuthOK 处理 认证:

# 追加到 server.py 文件

oauth = OAuth(app)

oauth.register(
"authok",
client_id=env.get("AUTHOK_CLIENT_ID"),
client_secret=env.get("AUTHOK_CLIENT_SECRET"),
client_kwargs={
"scope": "openid profile email",
},
server_metadata_url=f'https://{env.get("AUTHOK_DOMAIN")}/.well-known/openid-configuration'
)

设置路由

通过 /login 触发认证

# 追加到 server.py 文件

@app.route("/login")
def login():
return oauth.authok.authorize_redirect(
redirect_uri=url_for("callback", _external=True)
)

通过 /callback 处理认证回调

# 追加到 server.py 文件

@app.route("/callback", methods=["GET", "POST"])
def callback():
token = oauth.authok.authorize_access_token()
session["user"] = token
return redirect("/")

通过 /logout 路由清除会话

# 追加到 server.py 文件

@app.route("/logout")
def logout():
session.clear()
return redirect(
"https://" + env.get("AUTHOK_DOMAIN")
+ "/v1/logout?"
+ urlencode(
{
"return_to": url_for("home", _external=True),
"client_id": env.get("AUTHOK_CLIENT_ID"),
},
quote_via=quote_plus,
)
)

/home 路由

# 追加到 server.py 文件

@app.route("/")
def home():
return render_template("home.html", session=session.get('user'), pretty=json.dumps(session.get('user'), indent=4))

Server 实例化

# 追加到 server.py 文件

if __name__ == "__main__":
app.run(host="0.0.0.0", port=env.get("PORT", 3000))

添加模版

templates/home.html
<html>
<head>
<meta charset="utf-8" />
<title>AuthOK 示例</title>
</head>
<body>
{% if session %}
<h1>欢迎 {{session.userinfo.name}}!</h1>
<p><a href="/logout">注销</a></p>
<div><pre>{{pretty}}</pre></div>
{% else %}
<h1>欢迎您</h1>
<p><a href="/login">登录</a></p>
{% endif %}
</body>
</html>

运行应用

python3 server.py