chainlit身份验证方案oauth2.0及常用社交应用账户集成
阅读原文
建议阅读原文,始终查看最新文档版本,获得最佳阅读体验:《chainlit身份验证方案oauth2.0及常用社交应用账户集成》
本文摘要
本文详细说明了如何将chainlit与Microsoft AD(LDAP)集成,以便于企业用户通过域账号登录到chainlit,另外,还简要介绍了两个功能类似的开源项目lobechat和librechat。
chainlit简介
github网址:Chainlit/chainlit: Build Conversational AI in minutes ⚡️
chainlit是一个用于快速构建AI对话式聊天机器人的开源python库,其最大的特点是,可以很方便的构建类似于chatGPT那样的前端页面
类似的开源项目
Lobe Chat
lobe-chat/README.zh-CN.md at main · lobehub/lobe-chat
LobeHub - LobeChat:个人 LLM 效能工具,超越 ChatGPT / OLLaMA 使用体验
lobechat是现代化设计的开源 ChatGPT/LLMs 聊天应用与开发框架支持语音合成、多模态、可扩展的(function call)插件系统,一键免费拥有你自己的 ChatGPT/Gemini/Claude/Ollama 应用
lobechat也是支持OAuth2.0的
lobechat的github stars数远高于librechat和chainlit,高达6万多。
LibreChat
librechat.ai/docs danny-avila/LibreChat: Enhanced ChatGPT Clone: Features Agents, DeepSeek, Anthropic, AWS, OpenAI, Assistants API, Azure, Groq, o1, GPT-4o, Mistral, OpenRouter, Vertex AI, Gemini, Artifacts, AI model switching, message search, Code Interpreter, langchain, DALL-E-3, OpenAPI Actions, Functions, Secure Multi-User Auth, Presets, open-source for self-hosting. Active project.
官方介绍视频:https://youtu.be/ilfwGQtJNlI
LibreChat 是一款面向所有人工智能对话的终极开源应用程序,它完全可定制且兼容任何AI服务提供商——所有这些功能都集成在一个时尚流畅的界面中
LibreChat原生支持LDAP,同时也支持OAuth2.0

chainlit支持的身份验证提供商
参考资料:Overview - Chainlit
chainlit支持这三种身份认证方式:

其中OAuth又包括了以下几种,可以看到,支持的OAuth providers是非常多的,几乎包含了所有的社交账号,而keycloak本身也支持很多平台。

安装chainlit
Linux系统
首先要安装python和pip,此过程省略
注意,下面几行命令是在ubuntu desktop 24.04系统上运行的,Windows系统命令有所区别
#创建虚拟环境
python3 -m venv chainlit
#激活虚拟环境
source ./chainlit/bin/activate
#用pip安装chainlit包
pip install --upgrade chainlit


Windows系统,trae(vs code)
先通过trae(用vs code或cursor也是可以的)创建一个空的app.py文件,然后通过命令面板创建虚拟环境

成功创建虚拟环境后,就可以在资源管理中看到自动生成了.env文件夹

激活虚拟环境
.venv\Scripts\activate

检查当前python解释器是不是虚拟环境中的解释器,如果不是,务必选择虚拟环境中的解释器

用pip安装chainlit包,时间会比较长,因为国内下载包会比较慢
pip install --upgrade chainlit
用github验证身份
创建一个github app
参考资料:OAuth - Chainlit
点击此链接,然后创建一个github app
下图是我已经创建好的一个github app
关键是callback url、client secret(可以直接生成)
Request user authorization (OAuth) during installation这个一定要勾选。
webhook不用勾选
private key也是必须的,直接生成即可,网页会提示的

安装github app
注册好github app后,还要安装此github app,很简单,点击install app,然后右侧会显示待安装和已安装的github app,下图是我已经安装的github app

验证
启动chainlit app
chainlit run .\text_to_SQL.py -d -w
text_to_SQL.py代码如下:
import os
from openai import AsyncOpenAI
from chainlit.oauth_providers import OAuthProvider
import chainlit as cl
import httpx
from fastapi import HTTPException
from chainlit.user import User
import json
cl.instrument_openai()
""" import os
# 手动加载.env文件
from dotenv import load_dotenv
load_dotenv() """
# 打印环境变量
""" print(os.getenv("OAUTH_KEYCLOAK_BASE_URL"))
print(os.getenv("OAUTH_KEYCLOAK_REALM"))
print(os.getenv("OAUTH_KEYCLOAK_CLIENT_ID"))
print(os.getenv("OAUTH_KEYCLOAK_CLIENT_SECRET"))
print(os.getenv("OAUTH_KEYCLOAK_NAME")) """
#user_env = cl.user_session.get("env") #从.env文件中获取环境变量
# 从环境变量中获取API KEY
api_key = os.getenv("OPENAI_API_KEY")
api_key = "<此处替换为你的api_key>"
print(os.getenv("OPENAI_API_KEY"))
if api_key is None:
raise ValueError("OPENAI_API_KEY environment variable is not set.")
client = AsyncOpenAI(
api_key=api_key,
base_url="https://dashscope.aliyuncs.com/compatible-mode/v1"
)
# 优化后的模板,让指令更清晰
template = """SQL tables (and columns):
* Customers(customer_id, signup_date)
* Streaming(customer_id, video_id, watch_date, watch_minutes)
Generate a well - written SQL query to {input} and return the query wrapped in triple backticks (```):
```"""
settings = {
"model": "qwen-plus",
"temperature": 0,
"max_tokens": 500,
"top_p": 1,
"frequency_penalty": 0,
"presence_penalty": 0,
# 可以尝试去掉 stop 参数
# "stop": ["```"],
}
@cl.set_starters
async def starters():
return [
cl.Starter(
label=">50 minutes watched",
message="Compute the number of customers who watched more than 50 minutes of video this month."
)
]
@cl.on_message
async def main(message: cl.Message):
try:
stream = await client.chat.completions.create(
messages=[
{
"role": "user",
"content": template.format(input=message.content),
}
], stream=True, **settings
)
msg = await cl.Message(content="", language="sql").send()
async for part in stream:
if token := part.choices[0].delta.content or "":
await msg.stream_token(token)
await msg.update()
except Exception as e:
# 打印详细的错误信息
print(f"Error occurred: {
e}")
error_msg = await cl.Message(content=f"An error occurred: {
e}").send()
from typing import Dict, Optional
@cl.oauth_callback
def oauth_callback(
provider_id: str,
token: str,
raw_user_data: Dict[str, str],
default_user: cl.User,
) -> Optional[cl.User]:
return default_user
.env文件如下

DASHSCOPE_API_KEY=<此处替换为你的api_key>
OPENAI_API_KEY=<此处替换为你的api_key>
#下面的环境变量值,可以在github app中查到
OAUTH_GITHUB_CLIENT_ID=<此处替换为你的GITHUB_CLIENT_ID>
OAUTH_GITHUB_CLIENT_SECRET=<此处替换为你的GITHUB_CLIENT_SECRET>
会自动打开默认浏览器,自动打开网页,网址为http://localhost:8000
如下图,点击“继续使用github”,然后会跳转到github的登录界面,提示需要授权,完成授权后,网页会自动跳转回chainlit页面

可以看到,成功登录了

问聊天机器人,也输出了回答

下面是chainlit部分日志
2025-06-11 11:13:30 - HTTP Request: GET https://api.github.com/user "HTTP/1.1 200 OK"
2025-06-11 11:13:31 - HTTP Request: GET https://api.github.com/user/emails "HTTP/1.1 200 OK"
INFO: 127.0.0.1:60250 - "GET /auth/oauth/github/callback?code=c57134e83b9aa8f9411b&state=im0fiESYJ7wlUrS%24%2FpJ%40t%40%3ER03DsRQRG HTTP/1.1" 302 Found
INFO: 127.0.0.1:60250 - "GET /login/callback?success=True HTTP/1.1" 200 OK
INFO: 127.0.0.1:60250 - "GET /auth/config HTTP/1.1" 200 OK
INFO: 127.0.0.1:60249 - "GET /user HTTP/1.1" 200 OK
INFO: 127.0.0.1:60252 - "GET /project/translations?language=zh-CN& HTTP/1.1" 200 OK
2025-06-11 11:13:31 - Translated markdown file for zh-CN not found. Defaulting to chainlit.md.
INFO: 127.0.0.1:60252 - "GET /project/settings?language=zh-CN& HTTP/1.1" 200 OK
INFO: 127.0.0.1:60252 - "POST /set-session-cookie HTTP/1.1" 200 OK
INFO: 127.0.0.1:60252 - "GET /ws/socket.io/?EIO=4&transport=polling&t=PTS-eSY HTTP/1.1" 200 OK
INFO: 127.0.0.1:60252 - "POST /ws/socket.io/?EIO=4&transport=polling&t=PTS-eSk&sid=BhVCTPSnvJ-ahsFyAAAE HTTP/1.1" 200 OK
INFO: 127.0.0.1:60249 - "GET /ws/socket.io/?EIO=4&transport=polling&t=PTS-eSl&sid=BhVCTPSnvJ-ahsFyAAAE HTTP/1.1" 200 OK
INFO: 127.0.0.1:60249 - "POST /ws/socket.io/?EIO=4&transport=polling&t=PTS-eTB&sid=BhVCTPSnvJ-ahsFyAAAE HTTP/1.1" 200 OK
INFO: 127.0.0.1:60252 - "GET /ws/socket.io/?EIO=4&transport=polling&t=PTS-eTA&sid=BhVCTPSnvJ-ahsFyAAAE HTTP/1.1" 200 OK
INFO: 127.0.0.1:60252 - "GET /ws/socket.io/?EIO=4&transport=polling&t=PTS-eTd&sid=BhVCTPSnvJ-ahsFyAAAE HTTP/1.1" 200 OK
INFO: ('127.0.0.1', 60344) - "WebSocket /ws/socket.io/?EIO=4&transport=websocket&sid=BhVCTPSnvJ-ahsFyAAAE" [accepted]
INFO: 127.0.0.1:60252 - "GET /ws/socket.io/?EIO=4&transport=polling&t=PTS-eTm&sid=BhVCTPSnvJ-ahsFyAAAE HTTP/1.1" 200 OK
INFO: 127.0.0.1:60452 - "GET /user HTTP/1.1" 200 OK
INFO: 127.0.0.1:60453 - "GET /project/translations?language=zh-CN& HTTP/1.1" 200 OK
INFO: 127.0.0.1:60456 - "GET /user HTTP/1.1" 200 OK
INFO: 127.0.0.1:60456 - "GET /project/translations?language=zh-CN& HTTP/1.1" 200 OK
INFO: 127.0.0.1:60484 - "GET /user HTTP/1.1" 200 OK
INFO: 127.0.0.1:60484 - "GET /project/translations?language=zh-CN& HTTP/1.1" 200 OK
INFO: 127.0.0.1:60529 - "GET /user HTTP/1.1" 200 OK
INFO: 127.0.0.1:60529 - "GET /project/translations?language=zh-CN& HTTP/1.1" 200 OK
INFO: 127.0.0.1:60629 - "GET /user HTTP/1.1" 200 OK
INFO: 127.0.0.1:60630 - "GET /project/translations?language=zh-CN& HTTP/1.1" 200 OK
2025-06-11 11:14:44 - HTTP Request: POST https://dashscope.aliyuncs.com/compatible-mode/v1/chat/completions "HTTP/1.1 200 OK"
INFO: 127.0.0.1:60630 - "GET /user HTTP/1.1" 200 OK
关于https的特别说明
github的安全策略要求生产环境下,callback url必须使用https
但是开发环境下,可以使用http,不过callback url中的ip地址必须是localhost或127.0.0.1

keycloak–LDAP
部署keycloak
最简单的方法是用docker部署
docker run -p 8080:8080 -e KC_BOOTSTRAP_ADMIN_USERNAME=admin -e KC_BOOTSTRAP_ADMIN_PASSWORD=admin --dns=192.168.124.7 docker.1ms.run/keycloak/keycloak:26.2.5 start-dev
注意,这种方式,只适用于实验环境,生产环境尽量用helm部署,且必须用https
添加一个LDAP provider
访问keycloak,网址为:http://your_serverIP:8080
默认的用户名和密码都是admin

下面是一个示例:

验证ldap连接性


创建一个新的client


参考资料:OAuth - Chainlit
官方文档,对于redirect URLs的说明如下,其实关键是callback前的字符,这个是可以自定义的,我设置的是chainlit-keycloak
You have the option of changing the id of your Keycloak provider, which by default is keycloak. This is useful if you want to display a more appropriate name on your login page. Use the OAUTH_KEYCLOAK_NAME environment variable to set the name. Don’t choose an id that conflicts with any of the other Oauth providers.
The callback URL for your client should be: CHAINLIT_URL/auth/oauth/ O A U T H _ K E Y C L O A K _ N A M E / c a l l b a c k . I f y o u r C h a i n l i t a p p i s h o s t e d a t l o c a l h o s t : 8000 , y o u s h o u l d u s e [ h t t p : / / l o c a l h o s t : 8000 / a u t h / o a u t h / {OAUTH\_KEYCLOAK\_NAME}/callback. If your Chainlit app is hosted at localhost:8000, you should use[http://localhost:8000/auth/oauth/ OAUTH_K

最低0.47元/天 解锁文章

2552

被折叠的 条评论
为什么被折叠?



