如何在Gatsby搭配无头CMS WordPress中实现用户认证功能?
Gatsby + 无头WordPress 实现用户注册、认证与客户专区方案
一、WordPress端配置(核心是开放可交互的API端点)
1. 启用用户注册权限
默认WordPress的REST API用户注册端点/wp-json/wp/v2/users仅对管理员开放,无法直接用于前端注册。在主题的functions.php中添加代码开放权限:
// 允许匿名用户注册 add_filter('rest_allow_anonymous_register', '__return_true'); // 限制新注册用户角色为订阅者 add_filter('rest_user_query', function($args, $request) { if ($request->get_method() === 'POST') { $args['role'] = 'subscriber'; } return $args; }, 10, 2);
2. 配置JWT认证(用于登录状态校验)
安装JWT Authentication for WP REST API插件,在wp-config.php中添加密钥配置:
define('JWT_AUTH_SECRET_KEY', '生成的随机密钥'); // 可用wp_generate_password()生成 define('JWT_AUTH_CORS_ENABLE', true);
同时在functions.php中添加CORS支持,避免Gatsby跨域请求被拦截:
add_action('init', function() { header("Access-Control-Allow-Origin: 你的Gatsby域名"); // 例如http://localhost:8000 header("Access-Control-Allow-Methods: GET, POST, PUT, DELETE, OPTIONS"); header("Access-Control-Allow-Headers: Content-Type, Authorization"); });
插件提供的核心端点:
- 登录获取Token:
POST /wp-json/jwt-auth/v1/token(传username和password) - 验证Token有效性:
POST /wp-json/jwt-auth/v1/token/validate - 刷新Token:
POST /wp-json/jwt-auth/v1/token/refresh
3. 自定义注册端点(可选,处理复杂逻辑)
如果需要额外字段校验、发送验证邮件等,可注册自定义REST端点:
add_action('rest_api_init', function() { register_rest_route('custom/v1', '/register', array( 'methods' => 'POST', 'callback' => 'custom_user_register', 'permission_callback' => '__return_true' )); }); function custom_user_register($request) { $params = $request->get_params(); // 必填字段校验 if (empty($params['username']) || empty($params['email']) || empty($params['password'])) { return new WP_Error('missing_fields', '必填字段缺失', array('status' => 400)); } // 创建用户 $user_id = wp_create_user($params['username'], $params['password'], $params['email']); if (is_wp_error($user_id)) { return new WP_Error('register_fail', $user_id->get_error_message(), array('status' => 400)); } // 可选:发送验证邮件、添加用户元数据 return array('status' => 'success', 'user_id' => $user_id); }
二、Gatsby端实现
1. 注册与登录逻辑
用React表单收集数据,通过fetch请求WordPress接口:
// 注册示例 const handleRegister = async (e) => { e.preventDefault(); const res = await fetch('https://你的WP域名/wp-json/custom/v1/register', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ username: 'testuser', email: 'test@example.com', password: 'testpass123' }) }); const data = await res.json(); if (data.status === 'success') { navigate('/login'); } else { console.error(data.message); } }; // 登录示例(获取JWT Token) const handleLogin = async (e) => { e.preventDefault(); const res = await fetch('https://你的WP域名/wp-json/jwt-auth/v1/token', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ username: 'testuser', password: 'testpass123' }) }); const data = await res.json(); if (data.token) { localStorage.setItem('wp_auth_token', data.token); localStorage.setItem('wp_refresh_token', data.refresh_token); navigate('/customer-area'); } else { console.error(data.message); } };
2. 全局登录状态管理
用React Context管理用户状态,避免重复校验:
// src/context/AuthContext.js import { createContext, useContext, useState, useEffect } from 'react'; const AuthContext = createContext(); export const AuthProvider = ({ children }) => { const [isAuthenticated, setIsAuthenticated] = useState(false); const [user, setUser] = useState(null); useEffect(() => { const token = localStorage.getItem('wp_auth_token'); if (token) { // 验证Token有效性 fetch('https://你的WP域名/wp-json/jwt-auth/v1/token/validate', { method: 'POST', headers: { 'Authorization': `Bearer ${token}` } }).then(res => res.json()) .then(data => { if (data.code === 'jwt_auth_valid_token') { setIsAuthenticated(true); // 获取当前用户信息 fetch('https://你的WP域名/wp-json/wp/v2/users/me', { headers: { 'Authorization': `Bearer ${token}` } }).then(res => res.json()) .then(userData => setUser(userData)); } else { localStorage.removeItem('wp_auth_token'); setIsAuthenticated(false); } }); } }, []); const logout = () => { localStorage.removeItem('wp_auth_token'); localStorage.removeItem('wp_refresh_token'); setIsAuthenticated(false); setUser(null); }; return ( <AuthContext.Provider value={{ isAuthenticated, user, logout }}> {children} </AuthContext.Provider> ); }; export const useAuth = () => useContext(AuthContext);
在gatsby-browser.js和gatsby-ssr.js中全局注入Provider:
import { AuthProvider } from './src/context/AuthContext'; export const wrapRootElement = ({ element }) => { return <AuthProvider>{element}</AuthProvider>; };
3. 客户专区路由保护
创建高阶组件拦截未登录用户访问:
// src/components/ProtectedRoute.js import { navigate } from 'gatsby'; import { useAuth } from '../context/AuthContext'; const ProtectedRoute = ({ children }) => { const { isAuthenticated } = useAuth(); if (!isAuthenticated) { navigate('/login'); return null; } return children; }; export default ProtectedRoute;
在客户专区页面使用:
// src/pages/customer-area.js import ProtectedRoute from '../components/ProtectedRoute'; import { useAuth } from '../context/AuthContext'; const CustomerArea = () => { const { user } = useAuth(); return ( <ProtectedRoute> <h1>客户专区</h1> <p>欢迎回来,{user.name}!</p> {/* 渲染用户专属内容 */} </ProtectedRoute> ); }; export default CustomerArea;
4. 获取用户专属数据
带Token请求WordPress接口获取用户专属内容:
// 获取用户专属订单示例 const fetchUserOrders = async () => { const token = localStorage.getItem('wp_auth_token'); const res = await fetch('https://你的WP域名/wp-json/custom/v1/user-orders', { headers: { 'Authorization': `Bearer ${token}` } }); const orders = await res.json(); // 渲染订单列表 };
三、注意事项
- 生产环境不要用
*作为CORS允许域名,指定你的Gatsby生产域名 - Token存储建议用HttpOnly Cookie替代localStorage,提升安全性
- 定期刷新Token,避免过期导致用户退出
- WordPress端要做好数据校验,防止恶意注册或注入攻击
内容的提问来源于stack exchange,提问作者Zia-ur-Rehman Rehmani
相关产品推荐
相关产品推荐

