回來(lái)的雞肉只會(huì)紅燒或者清燉?教你一個(gè)新吃法!不加一滴水!全家人都愛(ài)吃~
By 跟婆婆學(xué)做飯
1、雞肉用熱水燙一遍
2、加鹽焗雞粉
3、加入花生油
4、給雞按摩20分鐘
5、電飯鍋里鋪蔥姜
6、放入紅棗枸杞
7、倒入腌料汁
8、按煮飯鍵35分鐘
9、就出鍋啦~超級(jí)香!
做菜好吃都有技巧,我的每道菜都有小妙招,大家搜索“豆果”可以直接查看我的菜譜!
喜歡這個(gè)食譜記得收藏、關(guān)注哦!歡迎在下方留言分享您對(duì)這道美食的建議。
好吧,終于在 WPJAM Basic 中實(shí)現(xiàn)了 JWT 登錄和認(rèn)證功能,今天就整理一下,首先按照慣例做一些 JWT 的介紹。
JWT(JSON Web Token)是一種輕量級(jí)的、自包含的、通常用于身份驗(yàn)證和授權(quán)的令牌,它將用戶信息(如用戶ID、角色和權(quán)限等)編碼到一個(gè) JSON 對(duì)象中,然后對(duì)其進(jìn)行數(shù)字簽名,從而生成一個(gè)經(jīng)過(guò)簽名的令牌。
由于 JWT 在客戶端和服務(wù)器之間傳輸時(shí)是加密的,因此服務(wù)器可以輕松驗(yàn)證該令牌的有效性和真實(shí)性。JWT 常用于無(wú)狀態(tài)的 RESTful API,作為訪問(wèn)受保護(hù)資源的憑據(jù),可以在每次請(qǐng)求時(shí)附加在請(qǐng)求頭中,下圖是使用 JWT 的一個(gè)常見(jiàn)的交互流程:
JWT(JSON Web Token)由三部分組成,分別是:Header(頭部)、Payload(負(fù)載)和 Signature(簽名)。
這三部分使用點(diǎn)(.)分隔,合并為一個(gè)字符,如下所示:
header.payload.signature
Header(頭部):
Header 是一個(gè) JSON 對(duì)象,通常包含兩個(gè)屬性:alg 和 typ,alg 屬性表示簽名算法(如 HS256、RS256 等),typ 屬性表示令牌類(lèi)型,通常為 "JWT"。Header 會(huì)被 Base64Url 編碼,得到一個(gè)字符串。例如:
{
"alg": "HS256",
"typ": "JWT"
}
Payload(負(fù)載):
Payload 是一個(gè) JSON 對(duì)象,包含一些“聲明”(Claim),用于傳遞用戶信息和其他業(yè)務(wù)數(shù)據(jù),聲明可以是預(yù)定義的(如 iss、exp、sub 等),也可以是自定義的,Payload 會(huì)被 Base64Url 編碼,得到一個(gè)字符串。例如:
{
"sub": "1234567890",
"name": "John Doe",
"iat": 1516239022
}
下面這 7 個(gè)字段都是由官方所定義的,也就是預(yù)定義(Registered claims)的,但并不都是必需的,
另外聲明名稱只有三個(gè)字符,因?yàn)?JWT 意味著是緊湊的。
Signature(簽名):
簽名用于保證 JWT 的完整性和安全性,它是將 Header、Payload 和一個(gè)密鑰(Secret)通過(guò)簽名算法進(jìn)行加密得到的,簽名可以防止 JWT 被篡改和偽造,例如,使用 HMAC-SHA256 算法生成簽名的方法如下:
HMACSHA256(
base64UrlEncode(header) + "." +
base64UrlEncode(payload),
secret
)
將 Header、Payload 和 Signature 用點(diǎn)(.)連接起來(lái),就得到了一個(gè)完整的 JWT,例如:
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c
通過(guò)上面 JWT 的介紹和 JWT 結(jié)構(gòu)可知,生成 JWT,就是通過(guò)簽名算法和一個(gè)用于生成簽名的密鑰(Secret)對(duì) Payload 生成簽名:我們?yōu)榱朔奖憔椭恢С?SHA256 簽名算法:
function wpjam_generate_jwt($payload, $secret='', $header=[]){
//無(wú)法生成沒(méi)有設(shè)置過(guò)期時(shí)間的 JWT
if(empty($payload['exp'])){
return false;
}
$header=wp_parse_args($header, [
'alg'=> 'HS256',
'typ'=> 'JWT'
]);
if($header['alg']=='HS256'){
$header=base64_urlencode(wpjam_json_encode($header));
$payload=base64_urlencode(wpjam_json_encode($payload));
$jwt=$header.'.'.$payload;
$secret=$secret ?: wp_salt();
return $jwt.'.'.base64_urlencode(hash_hmac('sha256', $jwt, $secret, true));
}
}
上面的代碼首先對(duì) Header 和 Payload 進(jìn)行 JSON 編碼和 URL 安全的 Base64 編碼,生成簽名的密鑰(Secret)如果為空,則使用 WordPress 默認(rèn)的鹽值函數(shù)來(lái)生成,最后把 Header 和 Payload 和生成的簽名通過(guò)點(diǎn)(.)連接起來(lái)得到了一個(gè)完整的 JWT 。
那么怎么驗(yàn)證 JWT 呢,驗(yàn)證的過(guò)程就是生成的反過(guò)程:首先通過(guò)點(diǎn)(.)將 JWT 分割成 Header、Payload 和 Signature 三段,然后對(duì) Header 和 Payload 進(jìn)行 URL 安全的 Base64 解碼和JSON 解碼,通過(guò)簽名的密鑰最后驗(yàn)證簽名:
function wpjam_verify_jwt($token, $secret=''){
$tokens=explode('.', $token);
if(count($tokens) !=3){
return false;
}
list($header, $payload, $sign)=$tokens;
$jwt=$header.'.'.$payload;
$secret=$secret ?: wp_salt();
$header=wpjam_json_decode(base64_urldecode($header));
$payload=wpjam_json_decode(base64_urldecode($payload));
if(empty($header['alg']) || $header['alg'] !='HS256'){
return false;
}
if(!hash_equals(base64_urlencode(hash_hmac('sha256', $jwt, $secret, true)), $sign)){
return false;
}
//簽發(fā)時(shí)間大于當(dāng)前服務(wù)器時(shí)間驗(yàn)證失敗
if(isset($payload['iat']) && $payload['iat'] > time()){
return false;
}
//該nbf時(shí)間之前不接收處理該Token
if(isset($payload['nbf']) && $payload['nbf'] > time()){
return false;
}
//沒(méi)有設(shè)置過(guò)期時(shí)間,或過(guò)期時(shí)間小于當(dāng)前服務(wù)器時(shí)間驗(yàn)證失敗
if(empty($payload['exp']) || $payload['exp'] < time()){
return false;
}
return $payload;
}
我們這邊生成和驗(yàn)證函數(shù)有點(diǎn)特殊處理,就是都要實(shí)現(xiàn)過(guò)期時(shí)間設(shè)置,意思就是不能設(shè)置沒(méi)有過(guò)期時(shí)間的 JWT。
wpjam_generate_jwt 和 wpjam_verify_jwt 這兩個(gè)函數(shù)在 WPJAM Basic 中已經(jīng)內(nèi)置了,通過(guò)他們就可以在 WordPress 實(shí)現(xiàn) JWT 的生成和驗(yàn)證了。
特別提醒一下過(guò)程中用到的 URL 安全的 Base64 編碼和解碼函數(shù) base64_urlencode 和 base64_urldecode 也是在 WPJAM Basic 中定義了。