Authlib OAuth 2.0 HTTP 客户端完全指南:requests 与 HTTPX2 双实现详解 【免费下载链接】authlibThe ultimate Python library in building OAuth, OpenID Connect clients and servers. JWS, JWE, JWK, JWA, JWT included.项目地址https://gitcode.com/gh_mirrors/au/authlib点击查看免费下载本指南围绕 Authlib 官方文档 docs/oauth2/client/http/index.rst 及其配套的 requests 集成指南、httpx 集成指南 与 API 参考 展开系统讲解 Authlib 提供的三类 OAuth 2.0 HTTP 客户端requests_client.OAuth2Session、httpx_client.AsyncOAuth2Client以及断言Assertion/Service Account客户端覆盖授权码、隐式、密码、客户端凭证四种授权流程以及 PKCE、客户端认证、Token 自动刷新、撤销、内省、非标准服务兼容Compliance Fix与 OpenID Connect 集成等实战能力。读完本文你将能够在自己的 Python 项目中直接落地一套可复用的 OAuth 2.0 客户端接入方案。一、认识 Authlib 的 OAuth 2.0 HTTP 客户端Authlib 为 Python 生态中最流行的两个 HTTP 库提供了 OAuth 2.0 客户端实现它们共享同一套 API 设计实现类名底层 HTTP 库说明requestsauthlib.integrations.requests_client.OAuth2Sessionrequests可作为requests-oauthlib的直接替代品httpx2authlib.integrations.httpx_client.AsyncOAuth2Clienthttpx异步异步 OAuth 2.0 客户端httpx2authlib.integrations.httpx_client.OAuth2Clienthttpx同步httpx 同步版本requestsauthlib.integrations.requests_client.AssertionSessionrequests断言授权框架Service Accounthttpx2authlib.integrations.httpx_client.AsyncAssertionClient/AssertionClienthttpx异步/同步断言客户端requests_client.OAuth2Session与httpx_client.AsyncOAuth2Client的核心方法完全一致均继承自协议层基类OAuth2Client见 authlib/oauth2/client.py因此本文的多数示例可无缝切换使用。API 参考文档 docs/oauth2/client/http/api.rst 中列出的公开方法为register_client_auth_method注册自定义客户端认证方法create_authorization_url构造授权端点 URLfetch_token向 Token 端点换取访问令牌refresh_token刷新访问令牌revoke_token撤销令牌RFC 7009introspect_token内省令牌RFC 7662register_compliance_hook注册兼容性钩子以下各节将逐一讲解这些方法的实战用法与底层原理。二、授权码流程Authorization Code完整实操授权码流程分两步先将用户重定向到授权服务器再用回调中的code换取令牌。以 GitHub 为例client_id Your GitHub client ID client_secret Your GitHub client secret scope user:email # 我们想要获取用户的邮箱 # 使用 requests 实现 from authlib.integrations.requests_client import OAuth2Session client OAuth2Session(client_id, client_secret, scopescope) # 使用 httpx2 实现异步 from authlib.integrations.httpx_client import AsyncOAuth2Client client AsyncOAuth2Client(client_id, client_secret, scopescope)如需指定回调地址可通过redirect_uri参数指定。从 authlib/oauth2/client.py 的create_authorization_url源码可以看到redirect_uri和scope未显式传入时会被自动填充到授权请求中。2.1 重定向到授权端点与 OAuth 1 不同OAuth 2 没有 request token 环节。第一步是把用户带到远程授权服务器authorization_endpoint https://github.com/login/oauth/authorize uri, state client.create_authorization_url(authorization_endpoint) print(uri) # https://github.com/login/oauth/authorize?response_typecodeclient_idc..idscopeuser%3Aemailstated..tcreate_authorization_url返回(uri, state)元组。真实项目中你必须保存state以备后续校验CSRF 防护。从源码看未显式传入state时Authlib 会调用generate_token()自动生成一个随机 state。2.2 用回调 code 换取令牌授权服务器完成授权后会带着code和state参数重定向回你的站点https://example.com/github?code42..e9stated..t调用.fetch_token换取访问令牌该方法会自动校验state以防止 CSRF 攻击authorization_response https://example.com/github?code42..e9stated..t token_endpoint https://github.com/login/oauth/access_token token client.fetch_token(token_endpoint, authorization_responseauthorization_response) print(token) # { # access_token: e..ad, # token_type: bearer, # scope: user:email # }拿到令牌后即可访问用户受保护资源。测试 tests/clients/test_requests/test_oauth2_session.py 中的test_mis_match_state验证了state不匹配时会抛出MismatchingStateException。重要由于真实流程中浏览器会跳转到另一个网站同一个 session 无法被复用。回调阶段需要重新创建 session并传入之前保存的statestate restore_previous_state() # 使用 requests from authlib.integrations.requests_client import OAuth2Session client OAuth2Session(client_id, client_secret, statestate) # 使用 httpx2异步 from authlib.integrations.httpx_client import AsyncOAuth2Client client AsyncOAuth2Client(client_id, client_secret, statestate) await client.fetch_token(token_endpoint, authorization_responseauthorization_response)Authlib 内置的 Flask/Django 集成已封装好这套流程可参考 docs/oauth2/client/web/index.rst 中对应框架章节。2.3 grant_type 的自动推导fetch_token内部会根据传入参数自动猜测grant_type见 authlib/oauth2/client.py 的_guess_grant_type参数中含code→authorization_code参数中同时含username和password→password其余情况 →client_credentials也可以通过grant_type参数显式指定。此外fetch_token支持methodGET等非常规 Token 请求方式测试 test_fetch_token_get 验证了 GET 方式下参数会拼入 URL。2.4 为授权码流程添加 PKCERFC 7636Authlib 客户端可以自动处理 PKCE只需在create_authorization_url和fetch_token中传入code_verifierfrom authlib.common.security import generate_token client OAuth2Session(..., code_challenge_methodS256) code_verifier generate_token(48) uri, state client.create_authorization_url(authorization_endpoint, code_verifiercode_verifier) # ... token client.fetch_token(..., code_verifiercode_verifier)从 authlib/oauth2/client.py 的源码可以看到当code_verifier存在、response_type code且code_challenge_method S256时客户端会自动计算code_challenge并附加到授权 URL。S256挑战值的算法在 authlib/oauth2/rfc7636/challenge.py 中实现BASE64URL-ENCODE(SHA256(ASCII(code_verifier)))并校验code_verifier必须符合[a-zA-Z0-9\-._~]{43,128}的 RFC 规范。测试 test_code_challenge 验证了授权 URL 中会携带code_challenge与code_challenge_methodS256参数。三、其余三种授权流程3.1 隐式流程ImplicitOAuth2Session支持隐式授权只需将response_type设为tokenuri, state client.create_authorization_url(authorization_endpoint, response_typetoken) print(uri) # https://some-service.com/oauth/authorize?response_typetokenclient_idbe..4d...用户授权后授权服务器会重定向到你的redirect_uri响应 URL 形如https://example.com/cb#access_token2..WpAstatexyztoken_typebearerexpires_in3600使用.fetch_token从 URL fragment 中解析访问令牌注意此时无需传入 token endpointtoken client.fetch_token(authorization_responseauthorization_response) print(token) # {access_token: 2..WpA, token_type: bearer, expires_in: 3600}其底层实现是 authlib/oauth2/client.py当authorization_response含#时直接走token_from_fragment分支调用parse_implicit_response解析 fragment 参数。注意GitHub 不支持token响应类型请使用其他支持的服务测试。3.2 密码流程Password密码授权自 Version 0.5 起支持直接传入username和password换取令牌token client.fetch_token(token_endpoint, usernamea-name, passworda-password)3.3 客户端凭证流程Client Credentials若不传code也没有用户信息fetch_token会默认发起client_credentials请求但建议显式指定grant_typetoken client.fetch_token(token_endpoint) # 或显式指定 token client.fetch_token(token_endpoint, grant_typeclient_credentials)对应测试见 test_client_credentials_type其中验证了请求体包含grant_typeclient_credentials且自动携带已配置的scope。四、客户端认证Client Authentication在 Token 端点换取令牌时授权服务器通常要求客户端认证。Authlib 依据 RFC 7591 提供三种默认认证方法方法说明实现client_secret_basicHTTP Basic 认证默认authlib/oauth2/auth.pyclient_secret_post将凭证放入 POST 表单体authlib/oauth2/auth.pynone公开客户端不认证只附client_idauthlib/oauth2/auth.py默认值为client_secret_basic。从 authlib/oauth2/client.py 的源码可以看到当未指定token_endpoint_auth_method时若有client_secret则默认client_secret_basic否则默认none公开客户端revocation_endpoint_auth_method遵循同样的推断逻辑。通过token_endpoint_auth_method可切换认证方法client OAuth2Session(token_endpoint_auth_methodclient_secret_post)如果授权服务器需要其他认证手段可以自行构造auth对象并传给fetch_tokenauth YourAuth(...) token client.fetch_token(token_endpoint, authauth, ...)4.1 扩展客户端认证方法除了三种默认方法还可以通过.register_client_auth_method扩展。Authlib 额外提供了两种由 RFC 7523 与 OpenID Connect 定义的 JWT 认证方法client_secret_jwt用client_secret构造 JWT 认证默认算法 HS256private_key_jwt用私钥构造 JWT 认证默认算法 RS256requests 版本用法完整示例见 docs/oauth2/client/http/requests.rstfrom authlib.integrations.requests_client import OAuth2Session from authlib.oauth2.rfc7523 import ClientSecretJWT token_endpoint https://example.com/oauth/token session OAuth2Session( your-client-id, your-client-secret, token_endpoint_auth_methodClientSecretJWT(token_endpoint), ) session.fetch_token(token_endpoint)from authlib.integrations.requests_client import OAuth2Session from authlib.oauth2.rfc7523 import PrivateKeyJWT with open(your-private-key.pem, rb) as f: private_key f.read() token_endpoint https://example.com/oauth/token session OAuth2Session( your-client-id, private_key, token_endpoint_auth_methodPrivateKeyJWT(token_endpoint), ) session.fetch_token(token_endpoint)httpx 异步版本用法见 docs/oauth2/client/http/httpx.rstfrom authlib.integrations.httpx_client import AsyncOAuth2Client from authlib.oauth2.rfc7523 import ClientSecretJWT client AsyncOAuth2Client( your-client-id, your-client-secret, token_endpoint_auth_methodclient_secret_jwt ) token_endpoint https://example.com/oauth/token client.register_client_auth_method(ClientSecretJWT(token_endpoint)) client.fetch_token(token_endpoint)ClientSecretJWT/PrivateKeyJWT的实现在 authlib/oauth2/rfc7523/auth.py二者都会在请求体中追加client_assertion_typeurn:ietf:params:oauth:client-assertion-type:jwt-bearer与client_assertion参数。JWT 载荷按照 RFC 7523 构造iss和sub均为client_idaud为 Token 端点 URL并自动生成唯一jti防重放见 authlib/oauth2/rfc7523/assertion.py。4.2 自定义认证方法client_secret_uri实战有些非标准服务要求把client_id和client_secret拼在 URL 上发送 POST 请求对应 GitHub issue #158 的场景POST /oauth/token?grant_typecodecode...client_id...client_secret...自定义一个名为client_secret_uri的认证方法即可解决from authlib.common.urls import add_params_to_uri def auth_client_secret_uri(client, method, uri, headers, body): uri add_params_to_uri(uri, [ (client_id, client.client_id), (client_secret, client.client_secret), ]) uri uri body body return uri, headers, body client OAuth2Session( client_id, client_secret, token_endpoint_auth_methodclient_secret_uri, ... ) client.register_client_auth_method((client_secret_uri, auth_client_secret_uri))注册后客户端将以带签名的 URI 完成认证。也可以直接把函数赋给token_endpoint_auth_methodclient OAuth2Session( client_id, client_secret, token_endpoint_auth_methodauth_client_secret_uri, )其内部原理见 authlib/oauth2/client.pyregister_client_auth_method接受(名称, 函数)元组或带name属性的实例存入_auth_methods字典client_auth()在fetch_token、refresh_token、revoke_token、introspect_token时按名称查找并构造ClientAuth最终调用认证函数改写(uri, headers, body)。五、访问受保护资源拿到令牌后即可请求受保护资源。如果复用同一个 session无需任何额外操作account_url https://api.github.com/user resp client.get(account_url) # Response [200] resp.json() # {...}但真实流程中如前面授权码章节所述需要新建 session 并载入之前保存的令牌token restore_previous_token_from_database() # token 是一个必须包含 access_token、token_type 的字典 client OAuth2Session(client_id, client_secret, tokentoken) account_url https://api.github.com/user resp client.get(account_url)令牌放置位置token_placementBearer 令牌默认放在请求头Authorization: Bearer token中也可通过token_placement参数改为body或uri见 authlib/oauth2/auth.py 与 authlib/oauth2/rfc6750/parameters.py。测试 test_add_token_to_header/body/uri 逐一验证了三种放置方式。单独使用 OAuth2Auth如果令牌已到手也可以在 requests 中直接使用OAuth2Auth完成请求签名——但它不会自动刷新令牌token {token_type: bearer, access_token: ...., ...} auth OAuth2Auth(token) requests.get(url, authauth)OAuth2Auth的实现在 authlib/integrations/requests_client/oauth2_session.py它内部把令牌转成OAuth2Token并按token_type签名请求遇到不支持的token_type会抛出UnsupportedTokenTypeError。六、刷新与自动更新令牌令牌过期后可以手动刷新更佳方案是让 Authlib 在请求资源时自动刷新并更新令牌。6.1 自动刷新需配置 token_endpoint如果创建OAuth2Session时传入了token_endpoint参数Authlib 会在令牌过期时自动刷新openid_configuration requests.get(https://example.org/.well-known/openid-configuration).json() session OAuth2Session(…, token_endpointopenid_configuration[token_endpoint])默认在令牌实际过期前 60 秒就视为过期并触发刷新以避免时钟偏差clock skew问题。该提前量通过leeway参数控制默认值为 60见 authlib/oauth2/client.py。过期判定逻辑在 authlib/oauth2/rfc6749/wrappers.py 的OAuth2Token.is_expired(leeway)expires_at - leeway time.time()即为过期。测试 test_token_status2 演示了leeway对过期判定的影响。6.2 手动刷新调用refresh_token用refresh_token换取新的access_tokentoken restore_previous_token_from_database() new_token client.refresh_token(token_endpoint, refresh_tokentoken.refresh_token)从 authlib/oauth2/client.py 的源码可见未显式传入refresh_token时会自动从当前令牌中读取且若未配置scope会沿用初始化时的 scope刷新成功后如果响应中没有新的refresh_token客户端会保留旧值见 authlib/oauth2/client.py。6.3 通过 update_token 自动持久化Authlib 还支持在请求资源时自动刷新并调用你定义的update_token回调持久化新令牌def update_token(token, refresh_tokenNone, access_tokenNone): if refresh_token: item OAuth2Token.find(namename, refresh_tokenrefresh_token) elif access_token: item OAuth2Token.find(namename, access_tokenaccess_token) else: return # 更新旧令牌 item.access_token token[access_token] item.refresh_token token.get(refresh_token) item.expires_at token[expires_at] item.save() client OAuth2Session(client_id, client_secret, update_tokenupdate_token)此后发送资源请求时如果之前保存的令牌已过期客户端会自动调用.refresh_token并回调update_token保存新令牌token restore_previous_token_from_database() client.token token # 如果令牌已过期这次 GET 会自动完成令牌刷新 client.get(https://openidconnect.googleapis.com/v1/userinfo)测试 test_auto_refresh_token 验证了过期令牌下 GET 请求会触发update_token而client_credentials场景test_auto_refresh_token2中仅当传入update_token时才会在令牌过期后自动重取。异步版本AsyncOAuth2Client的update_token既可以是同步函数也可以是async函数async def update_token(token, refresh_tokenNone, access_tokenNone): if refresh_token: item await OAuth2Token.find(namename, refresh_tokenrefresh_token) elif access_token: item await OAuth2Token.find(namename, access_tokenaccess_token) else: return # 更新旧令牌 item.access_token token[access_token] item.refresh_token token.get(refresh_token) item.expires_at token[expires_at] await item.save()值得注意的一个实现细节AsyncOAuth2Client内部使用anyio.Lock同步协程见 authlib/integrations/httpx_client/oauth2_client.py防止并发请求同时触发多次令牌刷新。测试 test_auto_refresh_token4 用asyncio.gather并发发起 10 个请求最终update_token只被调用一次。七、撤销与内省令牌如果服务商支持令牌撤销RFC 7009与内省RFC 7662可以这样使用token_endpoint https://example.com/oauth/token token get_your_previous_saved_token() client.revoke_token(token_endpoint, tokentoken) client.introspect_token(token_endpoint, tokentoken)两个方法均支持token_type_hint参数access_token或refresh_token并会自动携带客户端认证revoke_token使用revocation_endpoint_auth_methodintrospect_token使用token_endpoint_auth_method见 authlib/oauth2/client.py。未显式传token时客户端会优先取refresh_token再取access_token。对应测试见 test_revoke_token 与 test_revoke_token。八、Compliance Fix适配非标准服务有些自称提供 OAuth API 的服务与标准存在细微差异甚至返回错误的 Content-Type。Authlib 通过 compliance hooks 解决这类问题可用的钩子类型钩子类型触发时机access_token_response令牌解析之前refresh_token_response刷新令牌解析之前protected_request发起资源请求之前此外源码 authlib/oauth2/client.py 还定义了refresh_token_request、revoke_token_request、introspect_token_request三类请求钩子protected_request钩子被挂载到token_auth.hooks在每次令牌签名后执行。以 Stackoverflow 为例它要求必须在查询字符串中附加site参数以保护用户资源且其响应不是 JSON 格式。可以这样修复from authlib.common.urls import add_params_to_uri, url_decode def _non_compliant_param_name(url, headers, data): params {site: stackoverflow} url add_params_to_uri(url, params) return url, headers, body def _fix_token_response(resp): data dict(url_decode(resp.text)) data[token_type] Bearer data[expires_in] int(data[expires]) resp.json lambda: data return resp session.register_compliance_hook( protected_request, _non_compliant_param_name) session.register_compliance_hook( access_token_response, _fix_token_response)对非protected_request类型的钩子register_compliance_hook会校验钩子类型是否在预定义集合内非法类型直接抛出ValueError测试见 test_register_compliance_hook。九、OAuth 2 OpenID Connect解析 id_token对支持 OpenID Connect 的服务只要 scope 中包含openid授权服务器就会在响应中返回id_tokenclient_id Your Google client ID client_secret Your Google client secret scope openid email profile # 使用 requests client OAuth2Session(client_id, client_secret, scopescope) # 使用 httpx2 client AsyncOAuth2Client(client_id, client_secret, scopescope)某些远程服务要求额外的 OpenID Connect 参数例如nonce你需要自己生成并传入create_authorization_urlfrom authlib.common.security import generate_token # 记得保存这个 nonce 供后续校验 nonce generate_token() client.create_authorization_url(url, redirect_urixxx, noncenonce, ...)fetch_token的返回值中包含id_tokenresp session.fetch_token(...) print(resp[id_token])id_token是一段 JWT 文本必须解析后才能使用。Authlib 提供了 OpenID Connect 的解析与校验工具from authlib.oidc.core import CodeIDToken from joserfc import jwt # 从 https://www.googleapis.com/oauth2/v3/certs 获取 keys token jwt.decode(resp[id_token], keys) claims CodeIDToken(token.claims, token.header) claims.validate()自 Authlib 1.7 起JWT 编解码统一使用 joserfc 库可参考 docs/upgrades/jose.rst 了解相关变更。十、断言客户端AssertionSession / Service AccountAssertionSession是 OAuth 2.0 授权框架RFC 7521的 requests 实现即通常所说的Service Account服务账号。配置好的AssertionSession会自动处理令牌授权——直接使用即可。以 Google Service Account 为例使用服务账号 JSON 配置文件中的信息import json from authlib.integrations.requests_client import AssertionSession with open(MyProject-1234.json) as f: conf json.load(f) token_uri conf[token_uri] header {alg: RS256} key_id conf.get(private_key_id) if key_id: header[kid] key_id # Google 将 scope 放在 payload 中 claims {scope: scope} session AssertionSession( token_endpointtoken_uri, issuerconf[client_email], audiencetoken_uri, claimsclaims, subjectNone, keyconf[private_key], headerheader, ) session.get(...) session.post(...)异步版本AsyncAssertionClient见 docs/oauth2/client/http/httpx.rstimport json from authlib.integrations.httpx_client import AsyncAssertionClient with open(MyProject-1234.json) as f: conf json.load(f) token_uri conf[token_uri] header {alg: RS256} key_id conf.get(private_key_id) if key_id: header[kid] key_id # Google 将 scope 放在 payload 中 claims {scope: scope} async def main(): client AsyncAssertionClient( token_endpointtoken_uri, issuerconf[client_email], audiencetoken_uri, claimsclaims, subjectNone, keyconf[private_key], headerheader, ) resp await client.get(...) resp await client.post(...)其底层行为见 authlib/oauth2/rfc7521/client.py 与 authlib/integrations/requests_client/assertion_session.py构造函数必须提供token_endpoint、issuer、subjectaudience未指定时默认等于token_endpoint每次请求前若令牌缺失或过期AssertionAuth.ensure_active_token会自动调用refresh_token()生成新的 JWT 断言并换发令牌断言 JWT 默认使用jwt-bearer授权类型urn:ietf:params:oauth:grant-type:jwt-bearer签名算法由header中的alg决定缺少alg会抛出ValueErrorJWT 载荷自动包含iss、aud、iat、exp默认有效期 3600 秒以及自动生成的唯一jti防重放每次刷新都会生成新的jti。这些行为均有测试覆盖tests/clients/test_requests/test_assertion_session.py断言请求体含assertion参数、test_assertion_includes_default_jtijti为 36 位唯一值、test_assertion_jti_is_unique_per_refresh每次刷新jti不同。十一、会话关闭与自签名证书11.1 正确关闭会话开发者应当在任务完成后关闭 requests/httpx 会话以释放底层连接。可以手动调用.close()或使用with上下文自动关闭session OAuth2Session(client_id, client_secret) session.get(url) session.close() with OAuth2Session(client_id, client_secret) as session: session.get(url)httpx 同步客户端用法相同异步客户端则需要await client.close()client OAuth2Client(client_id, client_secret) client.get(url) client.close() with OAuth2Client(client_id, client_secret) as client: client.get(url) # 异步版本 client AsyncOAuth2Client(client_id, client_secret) await client.get(url) await client.close() async with AsyncOAuth2Client(client_id, client_secret) as client: await client.get(url)Authlib 的内置 Web 框架客户端Flask/Django/Starlette/FastAPI会自动关闭每个会话无需手动处理。11.2 自签名证书RFC 8705 第 2.2 节对于使用自签名证书做双向 TLS 的场景可以通过环境变量CURL_CA_BUNDLE和REQUESTS_CA_BUNDLE指定 CA 证书文件REQUESTS_CA_BUNDLE/path/to/ca-cert.pem请务必只在开发环境中设置该环境变量。十二、API 一览下表汇总 docs/oauth2/client/http/api.rst 中列出的核心 API 及其在OAuth2Sessionrequests与AsyncOAuth2Clienthttpx两套实现中的行为方法作用关键参数create_authorization_url(url, stateNone, code_verifierNone, **kwargs)构造授权 URL返回(uri, state)response_type默认code、redirect_uri、scope、nonce、prompt、login_hintfetch_token(url, ..., authorization_responseNone, grant_typeNone, ...)换取令牌authorization_response含#时走隐式 fragment 解析code、username/password、code_verifier、methodPOST/GET、authrefresh_token(url, refresh_tokenNone, ...)用刷新令牌换取新访问令牌scope、auth未传refresh_token时取当前令牌值revoke_token(url, tokenNone, token_type_hintNone, ...)RFC 7009 令牌撤销token_type_hint可为access_token/refresh_tokenintrospect_token(url, tokenNone, token_type_hintNone, ...)RFC 7662 令牌内省同上register_client_auth_method(auth)注册自定义客户端认证方法接受(名称, 函数)元组或带name的实例register_compliance_hook(hook_type, hook)注册兼容性钩子支持access_token_response、refresh_token_request、refresh_token_response、protected_request、revoke_token_request、introspect_token_request构造函数常用参数见 authlib/integrations/requests_client/oauth2_session.py 的 docstringclient_id、client_secret、authorization_endpoint、token_endpoint、token_endpoint_auth_method、revocation_endpoint、revocation_endpoint_auth_method、scope、state、redirect_uri、token、token_placementheader/body/uri、update_token、leeway默认 60 秒、default_timeout。requests 版本额外支持proxies、verify、cert、trust_env等会话级配置见 authlib/integrations/requests_client/utils.py。十三、延伸阅读HTTP 客户端总览与授权码流程示例OAuth 2.0 for Requests含 JWT 客户端认证与 OAuth2AuthOAuth 2.0 for HTTPX2含异步用法与断言客户端OAuth 2.0 概念导读RFC 7523JWT 客户端认证与断言授权Web 框架客户端Flask/Django/Starlette/FastAPIJWT / JOSE 指南如果需要将这套 HTTP 客户端接入 Web 框架自动完成 state 管理、token 持久化与会话生命周期管理建议直接使用 Authlib 内置的 Flask/Django/Starlette/FastAPI 集成它们构建在本指南所述的同一套 OAuth 2.0 客户端核心之上。赞分享【免费下载链接】authlibThe ultimate Python library in building OAuth, OpenID Connect clients and servers. JWS, JWE, JWK, JWA, JWT included.项目地址https://gitcode.com/gh_mirrors/au/authlib点击查看免费下载相关推荐Elixir 状态管理实战用 Agent 封装可共享状态从 KV.Bucket 入门 OTPElixir 状态管理实战用 Agent 封装可共享状态从 KV.Bucket 入门 OTP 本文是 Elixir 官方 Mix OTP 指南 的“用用chroma.js打造专业数据可视化配色ColorBrewer调色板分位数分档实战用chroma.js打造专业数据可视化配色ColorBrewer调色板分位数分档实战 做数据可视化时颜色怎么配往往是最头疼的环节。 chroma.js深入理解Authlib中的OAuth 2.0客户端实现深入理解Authlib中的OAuth 2.0客户端实现 概述 Authlib是一个强大的Python认证库提供了完整的OAuth 2.0客户端实现。本文将详细上一篇res-downloader3分钟搞定全网资源嗅探无水印批量下载上手指南下一篇Navicat密码解密工具完整使用指南轻松找回遗忘的数据库密码 创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考