### Install Dependencies with pnpm Source: https://github.com/zreren/better-auth-wechat-example/blob/main/README.md Installs project dependencies using pnpm. This is a prerequisite for running the example. ```bash cd wechat-better-auth-minimal pnpm install ``` -------------------------------- ### Run Development Server Source: https://github.com/zreren/better-auth-wechat-example/blob/main/README.md Starts the Next.js development server on a specified port. This allows for local testing and development of the application. ```bash pnpm dev --port 3005 ``` -------------------------------- ### Browser-side Auth Client Setup Source: https://context7.com/zreren/better-auth-wechat-example/llms.txt Sets up a browser-side authentication client using 'better-auth/react' for making authentication requests. It requires a base URL for the authentication server and can be extended with plugins. Includes example functions for checking the current user session and signing out. ```typescript import { createAuthClient } from 'better-auth/react'; export const authClient = createAuthClient({ baseURL: 'http://localhost:3005', plugins: [], }); // Usage examples async function checkSession() { const res = await authClient.$fetch('/get-session', { method: 'GET' }); const user = res.data?.user; console.log('Current user:', user); // Returns: { id, email, name, image, emailVerified, ... } } async function signOut() { await authClient.$fetch('/sign-out', { method: 'POST' }); window.location.href = '/'; } ``` -------------------------------- ### Configure Environment Variables Source: https://github.com/zreren/better-auth-wechat-example/blob/main/README.md Sets up necessary environment variables by copying from `.env.example` to `.env.local`. Essential variables include base URL, WeChat AppID and AppSecret, and domain configuration. ```env NEXT_PUBLIC_BASE_URL=http://localhost:3005 WECHAT_APP_ID=your_wechat_open_platform_appid WECHAT_APP_SECRET=your_wechat_open_platform_appsecret WECHAT_SYNTHETIC_EMAIL_DOMAIN=wechat.local WECHAT_DEBUG=true NEXT_PUBLIC_WECHAT_DEBUG=true ``` -------------------------------- ### Handle WeChat OAuth Callback and Session Creation Source: https://context7.com/zreren/better-auth-wechat-example/llms.txt Describes the automatic handling of the WeChat OAuth callback by Better Auth. It details the internal steps: state validation, token exchange using the authorization code, fetching user profile, creating/updating user accounts, linking social accounts, and establishing a user session with a cookie. Includes examples of internal API calls for token exchange and user info retrieval, as well as synthetic email generation and account creation. ```typescript // The callback is automatically handled by Better Auth // GET /api/auth/oauth2/callback/wechat?code=OAUTH_CODE&state=STATE_TOKEN // Internal flow (automatic): // 1. Validates state token (CSRF protection) // 2. Exchanges authorization code for access token // 3. Fetches user profile from WeChat API // 4. Creates or updates user account // 5. Links WeChat account if user exists // 6. Creates session and sets cookie // 7. Redirects to callbackURL or newUserCallbackURL // Token exchange (internal) const tokenUrl = 'https://api.weixin.qq.com/sns/oauth2/access_token'; const params = { appid: 'YOUR_APPID', secret: 'YOUR_SECRET', code: 'OAUTH_CODE', grant_type: 'authorization_code' }; // User profile fetch (internal) const userInfoUrl = 'https://api.weixin.qq.com/sns/userinfo'; const userParams = { access_token: 'ACCESS_TOKEN', openid: 'USER_OPENID', lang: 'zh_CN' }; // Synthetic email generation const userId = profile.unionid || profile.openid; const email = `${userId}@wechat.local`; // Account creation await adapter.createOAuthUser( { email: email.toLowerCase(), emailVerified: true, name: profile.nickname, image: profile.headimgurl, }, { providerId: 'wechat', accountId: userId, accessToken: 'ACCESS_TOKEN', refreshToken: 'REFRESH_TOKEN', accessTokenExpiresAt: new Date(Date.now() + 7200 * 1000), scope: 'snsapi_login', } ); ``` -------------------------------- ### Better Auth Configuration (TypeScript) Source: https://github.com/zreren/better-auth-wechat-example/blob/main/README.md Configures Better Auth by registering the custom WeChat OAuth plugin. This file centralizes the authentication setup for the Next.js application. ```typescript // src/lib/auth.ts // Registers the WeChat OAuth plugin with Better Auth. ``` -------------------------------- ### WeChat OAuth Server Plugin (TypeScript) Source: https://github.com/zreren/better-auth-wechat-example/blob/main/README.md Defines the server-side plugin for WeChat OAuth, including routes for initiating the sign-in process (`/sign-in/wechat`) and handling the callback (`/oauth2/callback/wechat`). This code is part of the Better Auth configuration. ```typescript // src/lib/plugins/wechat-oauth.ts // Placeholder for the actual plugin code. Defines the WeChat OAuth endpoints. ``` -------------------------------- ### Environment Configuration with Zod Source: https://context7.com/zreren/better-auth-wechat-example/llms.txt Demonstrates type-safe environment variable validation using Zod schemas with '@t3-oss/env-nextjs'. It defines server-side and client-side environment variables, including WeChat API keys and authentication secrets, ensuring that required variables are present and correctly typed. Provides an example of accessing these variables in a type-safe manner. ```env # .env.local NEXT_PUBLIC_BASE_URL=http://localhost:3005 WECHAT_APP_ID=wx1234567890abcdef WECHAT_APP_SECRET=abcdef1234567890abcdef1234567890 WECHAT_SYNTHETIC_EMAIL_DOMAIN=wechat.local BETTER_AUTH_SECRET=your-secret-generated-with-openssl-rand-base64-32 WECHAT_DEBUG=true NEXT_PUBLIC_WECHAT_DEBUG=true ``` ```typescript // src/env.ts (automatic validation) import { createEnv } from '@t3-oss/env-nextjs'; import { z } from 'zod'; export const env = createEnv({ server: { BETTER_AUTH_SECRET: z.string().min(1), WECHAT_APP_ID: z.string().min(1), WECHAT_APP_SECRET: z.string().min(1), WECHAT_SYNTHETIC_EMAIL_DOMAIN: z.string().default('wechat.local'), WECHAT_DEBUG: z.coerce.boolean().default(false), }, client: { NEXT_PUBLIC_BASE_URL: z.string().url().default('http://localhost:3005'), NEXT_PUBLIC_WECHAT_DEBUG: z.coerce.boolean().default(false), }, runtimeEnv: { BETTER_AUTH_SECRET: process.env.BETTER_AUTH_SECRET, WECHAT_APP_ID: process.env.WECHAT_APP_ID, WECHAT_APP_SECRET: process.env.WECHAT_APP_SECRET, WECHAT_SYNTHETIC_EMAIL_DOMAIN: process.env.WECHAT_SYNTHETIC_EMAIL_DOMAIN, WECHAT_DEBUG: process.env.WECHAT_DEBUG, NEXT_PUBLIC_BASE_URL: process.env.NEXT_PUBLIC_BASE_URL, NEXT_PUBLIC_WECHAT_DEBUG: process.env.NEXT_PUBLIC_WECHAT_DEBUG, }, emptyStringAsUndefined: true, }); // Usage import { env } from '@/env'; console.log(env.WECHAT_APP_ID); // Type-safe access ``` -------------------------------- ### Integrate Better Auth with Next.js API Routes Source: https://context7.com/zreren/better-auth-wechat-example/llms.txt Connects the Better Auth instance to Next.js API routes using `toNextJsHandler`. This setup allows Next.js to handle all authentication-related requests, including sign-in, OAuth callbacks, session retrieval, and sign-out, through a single catch-all route. ```typescript // src/app/api/auth/[...all]/route.ts import { auth } from '@/lib/auth'; import { toNextJsHandler } from 'better-auth/next-js'; export const { POST, GET } = toNextJsHandler(auth); // Handles all auth routes: // POST /api/auth/sign-in/wechat // GET /api/auth/oauth2/callback/wechat // GET /api/auth/get-session // POST /api/auth/sign-out ``` -------------------------------- ### Configure WeChat OAuth Plugin with Better Auth Source: https://context7.com/zreren/better-auth-wechat-example/llms.txt Sets up the Better Auth configuration with a custom WeChat OAuth plugin. It initializes Better Auth with session settings, an in-memory adapter, and configures account linking. The WeChat OAuth plugin requires `appId` and `appSecret` from the WeChat Open Platform. ```typescript import { wechatOAuth } from './lib/plugins/wechat-oauth'; import { betterAuth } from 'better-auth'; import { memoryAdapter } from 'better-auth/adapters/memory'; export const auth = betterAuth({ baseURL: 'http://localhost:3005', appName: 'WeChat Demo', database: memoryAdapter({}), session: { cookieCache: { enabled: true, maxAge: 60 * 60 }, expiresIn: 60 * 60 * 24 * 7, updateAge: 60 * 60 * 24, freshAge: 0, }, socialProviders: {}, account: { accountLinking: { enabled: true, trustedProviders: ['wechat'] }, }, plugins: [ wechatOAuth({ appId: 'your_wechat_appid', appSecret: 'your_wechat_secret', lang: 'cn', // or 'en' }), ], }); ``` -------------------------------- ### Database Adapter Integration with Drizzle Source: https://context7.com/zreren/better-auth-wechat-example/llms.txt Integrates Better Auth with Drizzle ORM for persistent database storage using PostgreSQL or SQLite. This replaces the default memory adapter for production use cases. It requires initializing your Drizzle instance and configuring the adapter with the correct database provider. ```typescript import { betterAuth } from 'better-auth'; import { drizzleAdapter } from 'better-auth/adapters/drizzle'; import { drizzle } from 'drizzle-orm/better-sqlite3'; import Database from 'better-sqlite3'; // Example with Drizzle + PostgreSQL import { db as pgDb } from './db'; // Your Drizzle instance for PostgreSQL export const authPg = betterAuth({ baseURL: 'http://localhost:3005', database: drizzleAdapter(pgDb, { provider: 'pg', // or 'mysql' | 'sqlite' }), plugins: [ wechatOAuth({ appId: process.env.WECHAT_APP_ID, appSecret: process.env.WECHAT_APP_SECRET, lang: 'cn', }), ], }); // Example with Drizzle + SQLite const sqlite = new Database('auth.db'); const sqliteDb = drizzle(sqlite); export const authSqlite = betterAuth({ database: drizzleAdapter(sqliteDb, { provider: 'sqlite' }), // ... rest of config }); // Required schema tables (Better Auth manages these): // - user (id, email, emailVerified, name, image, createdAt, updatedAt) // - session (id, userId, expiresAt, token, createdAt, updatedAt) // - account (id, userId, accountId, providerId, accessToken, refreshToken, ...) ``` -------------------------------- ### Next.js API Adapter for Better Auth (TypeScript) Source: https://github.com/zreren/better-auth-wechat-example/blob/main/README.md Implements the Next.js API route handler for Better Auth, enabling the framework to communicate with the authentication library. This route typically catches all authentication-related requests. ```typescript // src/app/api/auth/[...all]/route.ts // Adapts Better Auth to work within Next.js API routes. ``` -------------------------------- ### WeChat QR Login Component (TypeScript/React) Source: https://github.com/zreren/better-auth-wechat-example/blob/main/README.md A client-side React component responsible for rendering the WeChat QR code login UI. It utilizes the `wxLogin.js` library to display the QR code and handle the login flow. ```typescript // src/components/WeChatQrLogin.tsx // Client component for WeChat QR login using wxLogin.js. ``` -------------------------------- ### WeChat QR Login CSS Styling Source: https://github.com/zreren/better-auth-wechat-example/blob/main/README.md Provides CSS overrides for the `wxLogin.js` iframe to adjust the size and appearance of the QR code login dialog. This ensures the UI fits within the application's design. ```css /* public/wechat-login.css */ /* Overrides for wxLogin.js iframe size. */ ``` -------------------------------- ### Initiate WeChat OAuth Login from Client Source: https://context7.com/zreren/better-auth-wechat-example/llms.txt Client-side function to initiate the WeChat OAuth flow by making a POST request to the `/sign-in/wechat` endpoint. It specifies callback URLs for success, errors, and new users, and requests to disable immediate redirection. The response contains the authorization URL and a redirect flag. ```typescript // Client-side request import { authClient } from '@/lib/auth-client'; async function initiateWeChatLogin() { const result = await authClient.$fetch('/sign-in/wechat', { method: 'POST', body: { callbackURL: '/dashboard', errorCallbackURL: '/auth/error', newUserCallbackURL: '/welcome', disableRedirect: true, }, }); // Response structure const { url, redirect } = result.data; // url: "https://open.weixin.qq.com/connect/qrconnect?appid=...&state=...#wechat_redirect" // redirect: false console.log('Authorization URL:', url); } ``` -------------------------------- ### Dashboard Page Session Management Source: https://context7.com/zreren/better-auth-wechat-example/llms.txt A React page component ('client' component) that fetches and displays user session information. It uses the 'authClient' to retrieve session data on component mount via a 'useEffect' hook. Handles loading and error states, displaying user details or appropriate messages based on authentication status. ```typescript 'use client'; import { useEffect, useState } from 'react'; import { authClient } from '@/lib/auth-client'; export default function DashboardPage() { const [user, setUser] = useState(null); const [loading, setLoading] = useState(true); useEffect(() => { (async () => { try { const res = await authClient.$fetch('/get-session', { method: 'GET' }); setUser(res.data?.user ?? null); } catch (e) { console.error('Session error:', e); } finally { setLoading(false); } })(); }, []); if (loading) return
Loading...
; if (!user) return
Not signed in
; return (

Welcome, {user.name}

Email: {user.email}

ID: {user.id}

avatar
); } ``` -------------------------------- ### React WeChat QR Login Component Source: https://context7.com/zreren/better-auth-wechat-example/llms.txt A React component that renders a WeChat QR code for login and manages the authentication flow. It dynamically loads the WeChat script, fetches authorization details, displays a QR code, polls for session updates, and handles redirects and cleanup. Requires a callback URL for redirection after successful authentication. ```typescript 'use client'; import { WeChatQrLogin } from '@/components/WeChatQrLogin'; import { useState } from 'react'; export default function LoginPage() { const [showLogin, setShowLogin] = useState(false); return (
{showLogin && ( )}
); } // Component behavior: // 1. Loads WeChat wxLogin.js script dynamically // 2. Fetches authorization URL from /sign-in/wechat // 3. Extracts appid, redirect_uri, state, scope from URL // 4. Renders QR code iframe (300x400px) // 5. Polls /get-session every 1.5s to detect login // 6. Redirects to callbackUrl when session detected // 7. Handles errors and loading states // 8. Auto-cleanup on unmount ``` === COMPLETE CONTENT === This response contains all available snippets from this library. No additional content exists. Do not make further requests.