mirror of
https://github.com/langgenius/dify.git
synced 2025-07-18 14:52:32 +00:00
54 lines
1.9 KiB
Python
54 lines
1.9 KiB
Python
import json
|
|
import uuid
|
|
|
|
from core.plugin.impl.base import BasePluginClient
|
|
from extensions.ext_redis import redis_client
|
|
|
|
|
|
class OAuthProxyService(BasePluginClient):
|
|
# Default max age for proxy context parameter in seconds
|
|
__MAX_AGE__ = 5 * 60 # 5 minutes
|
|
__KEY_PREFIX__ = "oauth_proxy_context:"
|
|
|
|
@staticmethod
|
|
def create_proxy_context(user_id: str, tenant_id: str, plugin_id: str, provider: str):
|
|
"""
|
|
Create a proxy context for an OAuth 2.0 authorization request.
|
|
|
|
This parameter is a crucial security measure to prevent Cross-Site Request
|
|
Forgery (CSRF) attacks. It works by generating a unique nonce and storing it
|
|
in a distributed cache (Redis) along with the user's session context.
|
|
|
|
The returned nonce should be included as the 'proxy_context' parameter in the
|
|
authorization URL. Upon callback, the `use_proxy_context` method
|
|
is used to verify the state, ensuring the request's integrity and authenticity,
|
|
and mitigating replay attacks.
|
|
"""
|
|
context_id = str(uuid.uuid4())
|
|
data = {
|
|
"user_id": user_id,
|
|
"plugin_id": plugin_id,
|
|
"tenant_id": tenant_id,
|
|
"provider": provider,
|
|
}
|
|
redis_client.setex(
|
|
f"{OAuthProxyService.__KEY_PREFIX__}{context_id}",
|
|
OAuthProxyService.__MAX_AGE__,
|
|
json.dumps(data),
|
|
)
|
|
return context_id
|
|
|
|
@staticmethod
|
|
def use_proxy_context(context_id: str):
|
|
"""
|
|
Validate the proxy context parameter.
|
|
This checks if the context_id is valid and not expired.
|
|
"""
|
|
if not context_id:
|
|
raise ValueError("context_id is required")
|
|
# get data from redis
|
|
data = redis_client.getdel(f"{OAuthProxyService.__KEY_PREFIX__}{context_id}")
|
|
if not data:
|
|
raise ValueError("context_id is invalid")
|
|
return json.loads(data)
|