[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"project-82093":3},{"id":4,"name":5,"fullName":6,"owner":7,"repo":5,"description":8,"homepage":9,"htmlUrl":9,"language":10,"languages":9,"totalLinesOfCode":9,"stars":11,"forks":12,"watchers":13,"openIssues":12,"contributorsCount":12,"subscribersCount":12,"size":12,"stars1d":12,"stars7d":14,"stars30d":15,"stars90d":12,"forks30d":12,"starsTrendScore":12,"compositeScore":12,"rankGlobal":9,"rankLanguage":9,"license":9,"archived":16,"fork":16,"defaultBranch":17,"hasWiki":18,"hasPages":16,"topics":19,"createdAt":9,"pushedAt":9,"updatedAt":20,"readmeContent":21,"aiSummary":22,"trendingCount":12,"starSnapshotCount":12,"syncStatus":15,"lastSyncTime":23,"discoverSource":24},82093,"dash-social-signin","budescode\u002Fdash-social-signin","budescode","Dash social sign‑in package with frontend buttons and server‑side OAuth verification helpers",null,"Python",38,0,34,1,2,false,"main",true,[],"2026-06-12 02:04:23","# dash-social-signin\n\nSocial sign-in for Dash, made simple. Drop-in OAuth buttons and server-side helpers for authorization and token verification.\n\n## Supported providers\n\nGoogle · Facebook · GitHub · X (Twitter) · LinkedIn · Microsoft · Apple · Discord · Slack\n\n## Why use it?\n\n**Built for Dash** — Most OAuth libraries are generic and don't account for Dash's layout system or asset pipeline. This package is built specifically for Dash.\n\n**One consistent API for all providers** — Every provider has quirks. Facebook uses a different token endpoint format. X requires PKCE. Apple requires a JWT as the client secret. This package smooths all of that over so you call the same functions regardless of provider.\n\n**Security built in** — PKCE prevents authorization code interception. A state token is generated per login attempt, stored server-side, and verified on callback. Tokens are never exposed to the browser — all exchange happens on your Flask\u002FDash backend.\n\n**Flexible** — Use the built-in `build_container()` for a ready-made UI, or skip it entirely and build your own buttons. The backend helpers work either way.\n\n---\n\n## Installation\n\n```bash\npip install dash-social-signin\n```\n\nStore your provider credentials in a `.env` file. Use [.env.example](.env.example) as the template. See [docs\u002FPROVIDERS.md](docs\u002FPROVIDERS.md) for step-by-step credential setup for all 9 providers.\n\n---\n\n## Quick Start\n\nThe setup is split into three sections depending on your integration needs:\n\n- **Section A** — Using the default pre-styled buttons\n- **Section B** — Building your own custom buttons\n- **Section C** — The mandatory backend routes (required by both A and B)\n\n---\n\n## Section A — Using the Default Buttons\n\nThe package ships ready-to-use styled OAuth buttons. Two steps to get them into your layout.\n\n**Step 1 — Copy assets into your app**\n\n```python\nfrom dash_social_signin import install_assets\n\ninstall_assets(\".\u002Fassets\")\n```\n\n**Step 2 — Mount the container in your layout**\n\n```python\nimport os\nfrom dash import Dash, html\nfrom dash_social_signin import build_container\nfrom dotenv import load_dotenv\n\nload_dotenv()\n\napp = Dash(__name__)\napp.server.secret_key = os.environ.get(\"DASH_SOCIAL_SIGNIN_SECRET\", \"change-me\")\n\nBASE_URL = os.environ.get(\"BASE_URL\", \"http:\u002F\u002Flocalhost:8050\")\n\napp.layout = html.Div([\n    build_container(\n        {\n            \"providers\": {\n                \"google\": {\n                    \"clientId\": os.environ.get(\"GOOGLE_CLIENT_ID\"),\n                    \"redirectUri\": f\"{BASE_URL}\u002Fauth\u002Fcallback?provider=google\",\n                    \"authUrl\": f\"{BASE_URL}\u002Fauth\u002Fstart\",\n                    \"extraParams\": {\"provider\": \"google\"},\n                    \"scope\": \"openid email profile\",\n                },\n                \"github\": {\n                    \"clientId\": os.environ.get(\"GITHUB_CLIENT_ID\"),\n                    \"redirectUri\": f\"{BASE_URL}\u002Fauth\u002Fcallback?provider=github\",\n                    \"authUrl\": f\"{BASE_URL}\u002Fauth\u002Fstart\",\n                    \"extraParams\": {\"provider\": \"github\"},\n                    \"scope\": \"read:user user:email\",\n                },\n            }\n        },\n        id=\"social-signin\",\n    )\n])\n```\n\nThe JS renders the buttons into the container automatically. `authUrl` points to your `\u002Fauth\u002Fstart` backend route — see Section C.\n\n---\n\n## Section B — Building Custom Buttons\n\nYou can skip `install_assets()` and `build_container()` entirely and design your own layout. The only requirement is that your buttons link to `\u002Fauth\u002Fstart` with the right query parameters.\n\nThis example uses `dash-bootstrap-components` and Font Awesome:\n\n```python\nimport os\nimport dash\nimport dash_bootstrap_components as dbc\nfrom dash import html\nfrom dotenv import load_dotenv\n\nload_dotenv()\n\napp = dash.Dash(\n    __name__,\n    external_stylesheets=[dbc.themes.BOOTSTRAP, dbc.icons.FONT_AWESOME]\n)\napp.server.secret_key = os.environ.get(\"DASH_SOCIAL_SIGNIN_SECRET\", \"change-me\")\n\nBASE_URL = os.environ.get(\"BASE_URL\", \"http:\u002F\u002Flocalhost:8050\")\n\napp.layout = html.Div([\n    html.H3(\"Sign in to your account\"),\n    html.A(\n        dbc.Button(\n            [html.I(className=\"fab fa-google me-2\"), \"Continue with Google\"],\n            color=\"danger\",\n            outline=True,\n            className=\"d-flex align-items-center px-4 py-2\",\n        ),\n        href=f\"\u002Fauth\u002Fstart?provider=google&scope=openid email profile&redirectUri={BASE_URL}\u002Fauth\u002Fcallback?provider=google\",\n        style={\"textDecoration\": \"none\"},\n    )\n], className=\"d-flex flex-column align-items-center justify-content-center vh-100\")\n```\n\nAny button or link that hits `\u002Fauth\u002Fstart?provider=\u003Cname>&scope=\u003Cscopes>` will work.\n\n---\n\n## Section C — The Mandatory Backend Routes\n\nBoth Section A and Section B rely on the same two server-side routes. These handle state generation, PKCE, and token exchange.\n\n### 1. `\u002Fauth\u002Fstart` — Initiate the login\n\nGenerates a PKCE verifier and a CSRF state token, stores them in the session, then redirects the user to the provider.\n\n```python\nimport os\nimport secrets\nfrom flask import redirect, request, session\nfrom dash_social_signin import build_authorize_url, build_pkce_challenge, build_pkce_verifier\nfrom dash_social_signin.oauth import PROVIDER_CONFIG\n\nBASE_URL = os.environ.get(\"BASE_URL\", \"http:\u002F\u002Flocalhost:8050\")\n\n@app.server.route(\"\u002Fauth\u002Fstart\")\ndef auth_start():\n    provider = request.args.get(\"provider\")\n    if not provider or provider not in PROVIDER_CONFIG:\n        return \"Invalid provider\", 400\n\n    state = secrets.token_urlsafe(16)\n    session[f\"oauth_state:{provider}\"] = state\n\n    verifier = build_pkce_verifier()\n    session[f\"pkce_verifier:{provider}\"] = verifier\n    challenge = build_pkce_challenge(verifier)\n\n    auth_url = build_authorize_url(\n        provider=provider,\n        client_id=os.environ.get(f\"{provider.upper()}_CLIENT_ID\"),\n        redirect_uri=f\"{BASE_URL}\u002Fauth\u002Fcallback?provider={provider}\",\n        scope=request.args.get(\"scope\"),\n        state=state,\n        code_challenge=challenge,\n    )\n\n    return redirect(auth_url)\n```\n\n### 2. `\u002Fauth\u002Fcallback` — Handle the provider redirect\n\nValidates the state, exchanges the authorization code for tokens, and fetches the user's profile.\n\n```python\nimport os\nfrom flask import jsonify, request, session\nfrom dash_social_signin import verify_oauth_callback\n\nBASE_URL = os.environ.get(\"BASE_URL\", \"http:\u002F\u002Flocalhost:8050\")\n\n@app.server.route(\"\u002Fauth\u002Fcallback\", methods=[\"GET\", \"POST\"])\ndef auth_callback():\n    # Apple sends a POST; all other providers send a GET\n    get_param = lambda k: request.args.get(k) or request.form.get(k)\n\n    provider = get_param(\"provider\")\n    code = get_param(\"code\")\n    if not provider or not code:\n        return \"Missing provider or code\", 400\n\n    # CSRF check\n    returned_state = get_param(\"state\")\n    expected_state = session.pop(f\"oauth_state:{provider}\", None)\n    if expected_state and returned_state != expected_state:\n        return \"Invalid state\", 400\n\n    code_verifier = session.pop(f\"pkce_verifier:{provider}\", None)\n\n    tokens, userinfo = verify_oauth_callback(\n        provider=provider,\n        code=code,\n        redirect_uri=f\"{BASE_URL}\u002Fauth\u002Fcallback?provider={provider}\",\n        client_id=os.environ.get(f\"{provider.upper()}_CLIENT_ID\"),\n        client_secret=os.environ.get(f\"{provider.upper()}_CLIENT_SECRET\"),\n        code_verifier=code_verifier,\n    )\n\n    # At this point you have the user's profile.\n    # Save to your database, set a session cookie, redirect to your dashboard.\n    return jsonify({\"provider\": provider, \"userinfo\": userinfo})\n```\n\n---\n\n## Security features\n\n**PKCE** — Before redirecting the user, a random verifier is generated and stored server-side. A SHA-256 hash of it (the challenge) is sent to the provider. When the code comes back, the verifier is sent with the token request. The provider checks they match — an intercepted code is useless without the verifier.\n\n**CSRF protection via state** — A random token is generated per login attempt and stored in the session. The provider echoes it back in the callback. If it doesn't match, the request is rejected.\n\n**Tokens stay on the server** — The browser never sees your client secret or access tokens. In production, store tokens in your database and give the user a session cookie — never return raw tokens to the frontend.\n\n---\n\n## Running your app\n\n```python\nimport os\n\nif __name__ == \"__main__\":\n    port = int(os.environ.get(\"PORT\", 8050))\n    app.run(host=\"0.0.0.0\", port=port, debug=True)\n```\n\n---\n\n## Deployment\n\nSet these environment variables before deploying (Use [.env.example](.env.example) as the template):\n\n```bash\nBASE_URL=https:\u002F\u002Fyour-domain.com\nDASH_SOCIAL_SIGNIN_SECRET=a-long-random-string\nGOOGLE_CLIENT_ID=...\nGOOGLE_CLIENT_SECRET=...\n# etc.\n```\n\nRegister your callback URL in each provider's developer console. The pattern is always:\n\n```\nhttps:\u002F\u002Fyour-domain.com\u002Fauth\u002Fcallback?provider=PROVIDER_NAME\n```\n\nFor local development replace with `http:\u002F\u002Flocalhost:8050`.\n\n| Provider  | Redirect URI                                                   |\n|-----------|----------------------------------------------------------------|\n| Google    | `https:\u002F\u002Fyour-domain.com\u002Fauth\u002Fcallback?provider=google`     |\n| Facebook  | `https:\u002F\u002Fyour-domain.com\u002Fauth\u002Fcallback?provider=facebook`   |\n| GitHub    | `https:\u002F\u002Fyour-domain.com\u002Fauth\u002Fcallback?provider=github`     |\n| X         | `https:\u002F\u002Fyour-domain.com\u002Fauth\u002Fcallback?provider=x`          |\n| LinkedIn  | `https:\u002F\u002Fyour-domain.com\u002Fauth\u002Fcallback?provider=linkedin`   |\n| Microsoft | `https:\u002F\u002Fyour-domain.com\u002Fauth\u002Fcallback?provider=microsoft`  |\n| Apple     | `https:\u002F\u002Fyour-domain.com\u002Fauth\u002Fcallback?provider=apple`      |\n| Discord   | `https:\u002F\u002Fyour-domain.com\u002Fauth\u002Fcallback?provider=discord`    |\n| Slack     | `https:\u002F\u002Fyour-domain.com\u002Fauth\u002Fcallback?provider=slack`      |\n\n---\n\n## What this package does NOT do\n\nIt handles OAuth. What you do after that — saving users to a database, managing sessions, handling logout, registration flows — is up to you. This is intentional. Every app has different requirements, and this package shouldn't force a database or session library on you.\n\nAfter `verify_oauth_callback()` returns `userinfo`, you have the user's name, email, and profile picture. The rest is your app's business logic.\n\n---\n\n## Example app\n\nSee [examples\u002Fapp.py](examples\u002Fapp.py) for a full runnable demo covering all 9 providers.\n\n```bash\npip install \"dash-social-signin[examples]\"\npython examples\u002Fapp.py\n```\n\n---\n\n## Provider credential setup\n\nFull step-by-step setup guides for all 9 providers: [docs\u002FPROVIDERS.md](docs\u002FPROVIDERS.md)\n\n---\n\n## Connect and contribute\n\n- PyPI: https:\u002F\u002Fpypi.org\u002Fproject\u002Fdash-social-signin\n- LinkedIn: https:\u002F\u002Fwww.linkedin.com\u002Fin\u002Fbudescode\n- PayPal: https:\u002F\u002Fwww.paypal.com\u002Fpaypalme\u002Fomonbudeemma\n\n## License\n\nMIT\n","dash-social-signin 是一个为 Dash 应用程序提供社交登录功能的 Python 包，支持多种前端按钮和后端 OAuth 验证辅助工具。其核心功能包括对 Google、Facebook、GitHub 等主流身份提供商的支持，通过统一的API简化了不同提供商之间的差异处理，并内置了安全机制如PKCE防止授权码拦截以及状态令牌验证等，确保用户认证过程的安全性。此外，该包还提供了灵活的集成选项，既可以直接使用预设样式的按钮快速部署，也允许开发者自定义UI组件，同时保证后台逻辑的一致性和安全性。适用于需要在Dash项目中添加便捷且安全的社会化登录功能的各种场景。","2026-06-11 04:07:42","CREATED_QUERY"]