WordPress 提供的標(biāo)準(zhǔn)身份認(rèn)證方式是基于 Cookie 的認(rèn)證,只要用戶登錄了儀表盤,WordPress 就會(huì)自動(dòng)幫我們?cè)O(shè)置好認(rèn)證 Cookie。REST API 中使用 Nonces 技術(shù)來避免 CSRF 問題,如果我們?cè)?WordPress 站點(diǎn)內(nèi)使用 REST API 處理用戶請(qǐng)求,我們可以使用基于 Nonces 的認(rèn)證方法,如果我們需要開發(fā)一個(gè)脫離了 WordPress 模版的單頁面應(yīng)用,就無法獲取 WordPress 幫我們?cè)O(shè)置 Nonce 隨機(jī)數(shù)了,這種情況下,我們需要使用其他方式進(jìn)行用戶認(rèn)證,今天我們來討論一下 WordPress REST API 基于 JWT 的身份驗(yàn)證。
安裝 JWT Authentication for WP REST API 插件為 WordPress REST API 增加 JWT 身份驗(yàn)證服務(wù)
WordPress 內(nèi)核并不支持基于 JWT 的身份驗(yàn)證,我們需要安裝 JWT Authentication for WP REST API 插件為 WordPress REST API 增加基于 JWT 的身份驗(yàn)證服務(wù)端。直接在 WordPress 儀表盤搜索該插件、安裝啟用即可。安裝插件之前,確保 WP REST API 是啟用狀態(tài),否則該插件不起任何作用。
JWT Authentication for WP REST API 插件的主機(jī)環(huán)境要求
- 最小 PHP 版本為 5.3.0,相信只支持 PHP 5.3 的主機(jī)現(xiàn)在已經(jīng)不多了
- 主機(jī)啟用了 HTTP 授權(quán)頭支持,如果你使用的共享主機(jī),大多數(shù)情況下是沒有啟用的,請(qǐng)聯(lián)系主機(jī)提供商啟用
配置 JWT Authentication for WP REST API
JWT 需要一個(gè)密鑰來對(duì)令牌進(jìn)行簽名,我們要確保這個(gè)密鑰是唯一的,且永遠(yuǎn)不要泄漏這個(gè)密鑰。配置 JWT 密鑰的方法很簡單,在 wp-config.php 里面增加一個(gè)常量即可。
define('JWT_AUTH_SECRET_KEY', 'your-top-secrect-key');
我們可以使用 WordPress 密鑰生成服務(wù)來生成這個(gè)密鑰:https://api.wordpress.org/secret-key/1.1/salt/
配置 CORS 支持
JWT Authentication for WP REST API 插件為我們提供了 CORS 支持,如果我們開發(fā)的頁面應(yīng)用和 WordPress 站點(diǎn)不是同一個(gè)域名,我們需要為 WordPress 開啟跨域(CORS)請(qǐng)求支持。開啟的方法也很簡單,在 wp-config.php 增加一個(gè)常量:
define('JWT_AUTH_CORS_ENABLE', true);
使用 JWT Authentication for WP REST API 進(jìn)行用戶身份驗(yàn)證
啟用并配置好 JWT Authentication 插件后,WP REST API 多了兩個(gè)端點(diǎn):
- /wp-json/jwt-auth/v1/token: 用于驗(yàn)證用戶名、密碼,并返回 Token
- /wp-json/jwt-auth/v1/token/validate:用于驗(yàn)證 Token 是否正確
其中 /wp-json/jwt-auth/v1/token 是 JWT Authentication 的入口端點(diǎn),我們就可以通過這個(gè)端點(diǎn)驗(yàn)證用戶憑證、用戶名和密碼了,通過驗(yàn)證后,REST API 會(huì)返回一個(gè)令牌,我們需要把這個(gè)令牌保存到 Cookie 或?yàn)g覽器本地存儲(chǔ)中以便在后續(xù)的請(qǐng)求中使用。下面的示例代碼是一個(gè)基于 Vue JS 項(xiàng)目中的用戶登錄方法。
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;
}
});
},
上面的代碼中,我們把用戶提交的用戶名和密碼發(fā)送到?/wp-json/jwt-auth/v1/token 端點(diǎn)中,驗(yàn)證通過后,我們把返回的 token 存儲(chǔ)到了 Cookie 中,然后跳轉(zhuǎn)到首頁。
使用從 JWT Authentication 獲取的 Token 在后續(xù)的請(qǐng)求中驗(yàn)證用戶身份
在上一步中,我們獲取了 JWT Authentication 返回的 Token 并存儲(chǔ)在了 Cookie 中,現(xiàn)在,我們就可以把這個(gè) Token 附加到每次 API 請(qǐng)求中來驗(yàn)證用戶身份了。我們只需要把 Cookie 中的 Token 附加到 HTTP 請(qǐng)求的 Authorization 中,就可以實(shí)現(xiàn)基于 Token 的用戶認(rèn)證了。
/**
* 需要認(rèn)證的 Http 請(qǐng)求
*/
export const HTTP_AUTH = axios.create({
baseURL : process.env.baseUrl,
headers : {
'Authorization': 'Bearer ' + Cookie.get('token')
}
});
JWT Authentication 插件會(huì)攔截每次 API 請(qǐng)求,查找授權(quán)頭,如果授權(quán)頭存在,JWT Authentication 會(huì)解碼 Token、對(duì) Token 進(jìn)行驗(yàn)證,然后根據(jù)驗(yàn)證結(jié)果返回對(duì)應(yīng)的狀態(tài)碼和授權(quán)信息。具體的返回狀態(tài)請(qǐng)移步 JWT Authentication for WP REST API 插件頁面查看。
通過使用?JWT Authentication for WP REST API 進(jìn)行用戶驗(yàn)證,我們可以把 WordPress 作為后端應(yīng)用程序,開發(fā)一個(gè)完全脫離 WordPress 模版系統(tǒng)的前端單頁面應(yīng)用。這樣的應(yīng)用可以是微信公眾號(hào)里面的頁面,可以是小程序,可以是基于 Web 技術(shù)的 App 或 桌面應(yīng)用程序。具體做成什么樣子的,就看我們的需要的。這篇文章只是介紹了脫離 WordPress 模版的用戶認(rèn)證方法。如果你有更好的方法,歡迎在評(píng)論中提出。


