OpenID 停用了Flask-OpenID 是一个用于集成OpenID 2.0 认证协议的 Flask 扩展。不过要注意这个协议和对应的扩展库已经过时了现代的应用都转向了基于 OAuth 2.0 的 OpenID Connect (OIDC)# 安装pip install Flask-OpenID## app.pyimport osfromflaskimportFlask,render_template,request,redirect,url_for,session,flashfromflask_openid import OpenID# --- 1. 应用配置和初始化 ---appFlask(__name__)app.secret_keyyour-secret-key-here # 请务必修改为一个强随机字符串# 设置临时文件存储路径的根目录# BASE_DIR os.path.abspath(os.path.dirname(__file__))# oid OpenID(app, os.path.join(BASE_DIR, tmp))oidOpenID(app,./tmp,safe_roots[])# 简化路径写法safe_roots用于安全验证# --- 2. 辅助函数在请求前加载用户 ---app.before_requestdeflookup_current_user():在每个请求前根据 session 中的 openid 加载当前用户信息 session.permanentTrue# 假设我们用 g 对象来存储当前用户fromflask import g g.userNoneifopenidinsession:# 这里简化处理实际应从数据库查询# g.user User.query.filter_by(openidsession[openid]).first()g.usersession[openid]# 演示用直接将openid作为用户标识# --- 3. 登录视图 (核心逻辑) ---app.route(/login,methods[GET,POST])oid.loginhandler # 装饰器标记为登录处理器deflogin():处理用户的登录请求和OpenID回调# 如果用户已登录直接重定向到下一页或主页ifg.userisnotNone:returnredirect(oid.get_next_url())ifrequest.methodPOST:# 获取用户在表单中输入的 OpenID 标识 URLopenid_urlrequest.form.get(openid)ifopenid_url:# 尝试登录并请求获取用户的邮箱和昵称returnoid.try_login(openid_url,ask_for[email,nickname])# GET 请求或未提供 OpenID URL 时显示登录表单returnrender_template(login.html,nextoid.get_next_url(),erroroid.fetch_error())oid.after_logindefcreate_or_login(resp):OpenID 认证成功后会回调此函数。resp 包含从 OpenID 提供者返回的用户信息 session[openid]resp.identity_url# 从响应中提取用户信息 (如果提供并且用户授权了)user_emailresp.emailifhasattr(resp,email)else user_nicknameresp.nicknameifhasattr(resp,nickname)else# 这里应该进行数据库操作根据 identity_url 查找或创建用户# 例如# user User.query.filter_by(openidresp.identity_url).first()# if user is None:# user User(openidresp.identity_url, emailuser_email, nicknameuser_nickname)# db.session.add(user)# db.session.commit()flash(登录成功)# 登录成功后跳转到登录前想访问的页面returnredirect(oid.get_next_url())# --- 4. 登出视图 ---app.route(/logout)deflogout():清除 session 中的用户标识退出登录 session.pop(openid,None)flash(您已成功登出。)returnredirect(url_for(login))# --- 5. 受保护的页面示例 ---# 实际使用中可以配合 Flask-Login 的 login_required 装饰器来保护页面app.route(/)defindex():ifg.userisNone:returnredirect(url_for(login))returnfHello,{g.user}!brahref/logout登出/a# templates/login.html!DOCTYPE htmlhtmlheadtitleOpenID 登录示例/title/headbodyh1OpenID 登录/h1formactionmethodpostinputtypetextnameopenidvaluehttps://your-openid-provider.com/inputtypehiddennamenextvalue{{ next }}/inputtypesubmitvalue登录//form{%iferror%}h4错误信息:{{error}}/h4{%endif%}/body/html浏览器(User)你的网站(mysite.com)OpenID 提供者(openid.com)||||GET/|||---------------------------|||302to/login|||---------------------------|||GET/login|||---------------------------|||200(loginform)|||---------------------------|||POST/login(openidurl)|||---------------------------||||oid.try_login()发现提供者地址||302to openid.com/login|||---------------------------|||GET/login(at openid.com)|||-------------------------------------------------------------|||(用户输入密码确认)||-------------------------------------------------------------|302to mysite.com/login?openid_complete...|GET/login?openid_complete...|||---------------------------||||oid.loginhandler 检测回调|||验证签名-调用 oid.after_login|||设置 session[openid]||302to/(next)|||---------------------------|||GET/|||---------------------------|||200(Hello,user)|||---------------------------||