WordPress 提供的标准身份认证方式是基于 Cookie 的认证,只要用户登录了仪表盘,WordPress 就会自动帮我们设置好认证 Cookie。REST API 中使用 Nonces 技术来避免 CSRF 问题,如果我们在 WordPress 站点内使用 REST API 处理用户请求,我们可以使用基于 Nonces 的认证方法,如果我们需要开发一个脱离了 WordPress 模版的单页面应用,我们就无法获取 WordPress 帮我们设置 Nonce 随机数了,这种情况下,我们需要使用其他方式进行用户认证,今天我们来讨论一下 WordPress REST API 基于 JWT 的身份验证。
安装 JWT Authentication for WP REST API 插件为 WordPress REST API 增加 JWT 身份验证服务
WordPress 内核并不支持基于 JWT 的身份验证,我们需要安装 JWT Authentication for WP REST API 插件为 WordPress REST API 增加基于 JWT 的身份验证服务端。直接在 WordPress 仪表盘搜索该插件、安装启用即可。安装插件之前,确保 WP REST API 是启用状态,否则该插件不起任何作用。
JWT Authentication for WP REST API 插件的主机环境要求
- 最小 PHP 版本为 5.3.0,相信只支持 PHP 5.3 的主机现在已经不多了
- 主机启用了 HTTP 授权头支持,如果你使用的共享主机,大多数情况下是没有启用的,请联系主机提供商启用
配置 JWT Authentication for WP REST API
JWT 需要一个密钥来对令牌进行签名,我们要确保这个密钥是唯一的,且永远不要泄漏这个密钥。配置 JWT 密钥的方法很简单,在 wp-config.php 里面增加一个常量即可。
define('JWT_AUTH_SECRET_KEY', 'your-top-secrect-key');
我们可以使用 WordPress 密钥生成服务来生成这个密钥:https://api.wordpress.org/secret-key/1.1/salt/
配置 CORS 支持
JWT Authentication for WP REST API 插件为我们提供了 CORS 支持,如果我们开发的但页面应用和 WordPress 站点不是同一个域名,我们需要为 WordPress 开启跨域(CORS)请求支持。开启的方法也很简单,在 wp-config.php 增加一个常量:
define('JWT_AUTH_CORS_ENABLE', true);
使用 JWT Authentication for WP REST API 进行用户身份验证
启用并配置好 JWT Authentication 插件后,WP REST API 多了两个端点:
- /wp-json/jwt-auth/v1/token: 用于验证用户名、密码,并返回 Token
- /wp-json/jwt-auth/v1/token/validate:用于验证 Token 是否正确
其中 /wp-json/jwt-auth/v1/token 是 JWT Authentication 的入口端点,我们就可以通过这个端点验证用户凭证、用户名和密码了,通过验证后,REST API 会返回一个令牌,我们需要把这个令牌保存到 Cookie 或浏览器的本地存储中以便在后续的请求中使用。下面的示利代码是一个基于 Vue JS 项目中的用户登录方法。
onLogin(formName) {
this.$refs[formName].validate((valid) => {
if (valid) {
HTTP.post('/wp-json/jwt-auth/v1/token', {
username: this.loginForm.username,
password: this.loginForm.password,
}).then(response => {
this.$store.commit('update', response.data.token);
Cookie.set('token', response.data.token);
this.$router.push('/');
}).catch(e => {
this.errors.push(e);
});
} else {
console.log('error submit!!');
return false;
}
});
},
上面的代码中,我们发送用户提交的用户名和密码到 /wp-json/jwt-auth/v1/token 端点中,验证通过后,我们把返回的 token 存储到了 Cookie 中,然后跳转到首页。
使用从 JWT Authentication 获取的 Token 在后续的请求中验证用户身份
在上一步中,我们获取了 JWT Authentication 返回的 Token 并存储在了 Cookie 中,现在,我们就可以把这个 Token 附加到每次 API 请求中来验证用户身份了。我们只需要把 Cookie 中的 Token 附加到 HTTP 请求的 Authorization 中,就可以实现基于 Token 的用户认证了。
/**
* 需要认证的 Http 请求
*/
export const HTTP_AUTH = axios.create({
baseURL : process.env.baseUrl,
headers : {
'Authorization': 'Bearer ' + Cookie.get('token')
}
});
JWT Authentication 插件会拦截每次 API 请求,查找授权头,如果授权头存在,JWT Authentication 会解码 Token、对 Token 进行验证,然后根据验证结果返回对应的状态码和授权信息。具体的返回状态请移步 JWT Authentication for WP REST API 插件页面查看。
通过使用 JWT Authentication for WP REST API 进行用户验证,我们可以把 WordPress 作为后端应用程序,开发一个完全脱离 WordPress 模版系统的前端单页面应用。这样的应用可以是 微信公众号里面的页面,可以是小程序,可以是基于 Web 技术的 App 或 桌面应用程序。具体做成什么样子的,就看我们的需要的。这篇文章只是介绍了脱离 WordPress 模版的用户认证方法。如果你有更好的方法,欢迎在评论中提出。