无需凭证获取已登录WordPress用户的JWT令牌方案咨询
安全获取已登录WordPress用户的JWT令牌方案
要解决硬编码密码获取JWT令牌的安全问题,核心思路是利用WordPress已登录用户的会话状态,在后端直接签发令牌,无需在前端传递敏感凭证。以下是基于jwt-authentication-for-wp-api插件的实现步骤:
1. 在子主题functions.php中添加自定义REST端点
这个端点仅对已登录用户开放,直接调用JWT插件的令牌生成逻辑,返回合法的JWT令牌:
// 注册自定义REST路由 add_action('rest_api_init', function () { register_rest_route( 'custom/v1', '/get-jwt-token', array( 'methods' => 'GET', 'callback' => 'generate_jwt_for_logged_in_user', 'permission_callback' => function () { // 仅允许已登录用户访问 return is_user_logged_in(); } ) ); }); // 生成JWT令牌的回调函数 function generate_jwt_for_logged_in_user() { $current_user = wp_get_current_user(); // 确保JWT插件已激活并加载 if (!class_exists('JWT_Auth')) { return new WP_Error('jwt_not_available', 'JWT插件未激活', array('status' => 403)); } // 调用JWT插件的方法生成令牌 $token = JWT_Auth::generate_token($current_user->ID); return rest_ensure_response(array( 'token' => $token, 'user_email' => $current_user->user_email, 'user_nicename' => $current_user->user_nicename, 'user_display_name' => $current_user->display_name )); }
2. 修改前端JS脚本,调用自定义端点
移除硬编码的密码,改为请求新的后端端点获取令牌:
// ---------------- User variables retrieved in Wordpress -------------------- var prenom_e = my_script_var_wp.prenom_wp; var nom_e = my_script_var_wp.nom_wp; var courriel_e = my_script_var_wp.courriel_wp; var username_e = my_script_var_wp.username_wp; // --- Transformation de variables --- // const firstname = prenom_e; const lastname = nom_e; const email = courriel_e; const username = username_e; // --------------Variables------------------------------ const urlInfoClient = "https://www.instance.fr"; // ----------------------------------------------------- // ---------------- API Environment URL's -------------------- const urlCustomGetToken = "https://instance.fr/wp-json/custom/v1/get-jwt-token"; const urlValidateToken = "https://instance.fr/wp-json/jwt-auth/v1/token/validate"; // ----------------------------------------------------- async function GenerateToken() { console.log(" "); console.log("GenerateToken() function"); const res = await fetch(urlCustomGetToken, { method: 'GET', credentials: 'include', // 携带WordPress会话Cookie,确保后端识别已登录用户 headers: { "Content-type": "application/json; charset=UTF-8" } }); if (res.status !== 200) { throw new Error(`Impossible de récuperer le token`); } let data = await res.json(); console.log(data); if (data && data.token) { letoken = data.token } else { console.log("La propriété 'token' n'existe pas dans la réponse JSON."); } } async function UseToken() { console.log(" "); console.log("UseToken() function"); var token = letoken; const res1 = await fetch( urlValidateToken, { method: 'POST', headers: { "Content-type": "application/json; charset=UTF-8", "Authorization": `Bearer ${token}` } } ); if (res1.status !== 200) { throw new Error(`Impossible de valider le token`); } let data1 = await res1.json(); console.log(data1); return data1; } // ---------------------actions------------------ window.addEventListener('DOMContentLoaded', (event) => { document.getElementById("auth_button").onclick = function () { GenerateToken() .then(() => UseToken()) .catch((erreur) => { console.error(erreur); }); }});
3. 关键安全注意事项
- 强制HTTPS传输:确保站点和API请求都使用HTTPS,防止令牌在传输过程中被窃听。
- 令牌过期配置:在
wp-config.php中设置令牌有效期,避免长期有效带来的风险:define('JWT_AUTH_EXPIRATION_TIME', 3600); // 1小时,可根据需求调整 - CORS配置:如果对接的是非WordPress域名,需要在
functions.php中添加CORS允许规则,避免跨域请求被拦截:add_action('rest_api_init', function () { remove_filter('rest_pre_serve_request', 'rest_send_cors_headers'); add_filter('rest_pre_serve_request', function ($value) { header('Access-Control-Allow-Origin: https://your-external-domain.com'); header('Access-Control-Allow-Methods: GET, POST, OPTIONS'); header('Access-Control-Allow-Credentials: true'); return $value; }); }, 15); - 权限控制:自定义端点的
permission_callback已确保仅登录用户访问,避免未授权请求获取令牌。
内容的提问来源于stack exchange,提问作者Ilias ASSADKI
相关产品推荐
相关产品推荐

