php設(shè)置token的方法:1、定義獲取Token的路由路徑;2、建立Service層;3、使用UserToken類處理整個(gè)邏輯;4、在Model層里建立User類;5、在驗(yàn)證器類和異常類創(chuàng)建相應(yīng)的驗(yàn)證方法和異常處理。
創(chuàng)新互聯(lián)堅(jiān)持“要么做到,要么別承諾”的工作理念,服務(wù)領(lǐng)域包括:網(wǎng)站設(shè)計(jì)、網(wǎng)站制作、企業(yè)官網(wǎng)、英文網(wǎng)站、手機(jī)端網(wǎng)站、網(wǎng)站推廣等服務(wù),滿足客戶于互聯(lián)網(wǎng)時(shí)代的老城網(wǎng)站設(shè)計(jì)、移動(dòng)媒體設(shè)計(jì)的需求,幫助企業(yè)找到有效的互聯(lián)網(wǎng)解決方案。努力成為您成熟可靠的網(wǎng)絡(luò)建設(shè)合作伙伴!
推薦:《PHP視頻教程》
PHP_設(shè)置權(quán)限令牌Token
我們開發(fā)的后端API接口會(huì)對(duì)訪問(wèn)者有一個(gè)權(quán)限要求,比如一些包含私人信息的接口,就需要訪問(wèn)者請(qǐng)求接口的同時(shí),傳遞一個(gè)提前已經(jīng)發(fā)放給訪問(wèn)者的Token。
這就像一個(gè)令牌一樣,只有訪問(wèn)者展示出來(lái)我們才會(huì)“通過(guò)放行”。
下面就記錄一下權(quán)限令牌的代碼編寫思路。
定義獲取Token的路由路徑,接受code參數(shù)(code來(lái)源:微信服務(wù)器,登錄系統(tǒng)基于微信體系)
建立Service層,在這層里創(chuàng)建Token基類和UserToken類
UserToken類處理整個(gè)邏輯:Token生成和返回
在Model層里建立User類,負(fù)責(zé)用戶數(shù)據(jù)表的讀寫,供Service層的UserToken調(diào)用
在驗(yàn)證器類和異常類創(chuàng)建相應(yīng)的驗(yàn)證方法和異常處理
控制器->Service層->Model層返回值給Service層->Service層返回值給控制器,整個(gè)流程完成Token令牌的編寫
二、具體說(shuō)明首先定義好路由路徑:
Route::post(
'api/:version/token/user',
'api/:version.Token/getToken'
);然后創(chuàng)建Token控制器,定義對(duì)應(yīng)路由路徑的getToken方法:
public function getToken($code='') {
(new TokenGet())->goCheck($code); // 驗(yàn)證器
$token = (new UserToken($code))->get();
return [
'token' => $token
];
}在調(diào)用Service層之前,還得檢查一下傳遞過(guò)來(lái)的參數(shù),于是定義TokenGet這個(gè)驗(yàn)證器:
class TokenGet extends BaseValidate
{
protected $rule = [
'code' => 'require|isNotEmpty'
];
protected $message = [
'code' => '需要code才能獲得Token!'
];
}回到Token控制器,驗(yàn)證通過(guò)后,我們調(diào)用Service層定義的UserToken類:
$token = (new UserToken($code))->get();復(fù)制代碼
這里討論一下Service層和Model層。我們普遍的理解是Service層是基于Model層的一次抽象封裝。
Model層只負(fù)責(zé)操作數(shù)據(jù)庫(kù)并返且返回給Service層然后Service層處理業(yè)務(wù)邏輯,最后返回給Controller層但我覺得小項(xiàng)目的話,Service其實(shí)和Model就有點(diǎn)平級(jí)的意思,因?yàn)橛行┖?jiǎn)單的接口Model層直接對(duì)接Controller就可以了,只有相對(duì)復(fù)雜的接口,比如用戶權(quán)限,就可以再經(jīng)過(guò)Service層分隔不同功能的代碼。
這樣的處理更加靈活,有大量確實(shí)很簡(jiǎn)單的接口就不用過(guò)一次Service層了,這樣更像是走過(guò)過(guò)場(chǎng)而已,沒(méi)什么意義了。
回到Service層的代碼編寫,由于Token還會(huì)有不同的種類,所以先創(chuàng)建一個(gè)Token基類,里面包含一些通用的方法。然后就是給訪問(wèn)者返回令牌的UserToken類的編寫了。
由于是基于微信,我們需要三個(gè)信息:code,appid,appsecret,然后通過(guò)構(gòu)造函數(shù)來(lái)給UserToken類賦上初始值:
function __construct($code) {
$this->code = $code;
$this->wxAppID = config('wx.app_id');
$this->wxAppSecret = config('wx.app_secret');
$this->wxLoginUrl = sprintf(
config('wx.login_url'),
$this->wxAppID, $this->wxAppSecret, $this->code
);
}然后把這三個(gè)放入微信提供的接口的參數(shù)位置,目的是獲得一個(gè)完整的微信服務(wù)器端的url,請(qǐng)求到我們需要的openid。
然后是通過(guò)發(fā)送網(wǎng)絡(luò)請(qǐng)求的步驟就在此略過(guò)。微信服務(wù)器會(huì)返回包含openid的對(duì)象,判斷這個(gè)對(duì)象的值沒(méi)問(wèn)題后,我們就開始生成令牌的步驟了,創(chuàng)建函數(shù)grantToken():
private function grantToken($openidObj) {
// 取出openid
$openid = $openidObj['openid'];
// 通過(guò)Model層調(diào)用數(shù)據(jù)庫(kù),檢查openid是否已經(jīng)存在
$user = UserModel::getByOpenID($openid);
// 如果存在,不處理,反之則新增一條user記錄
if ($user) {
$uid = $user->id;
} else {
// 不存在,生成一條數(shù)據(jù),具體方法略過(guò)
$uid = $this->newUser($openid);
}
// 生成令牌,寫入緩存(具體方法見下面的定義)
$cachedValue = $this->prepareCacheValue($openidObj, $uid);
$token = $this->saveToCache($cachedValue);
// 令牌返回到調(diào)用者端
return $token;
}
private function prepareCacheValue($openidObj, $uid) {
$cachedValue = $openidObj;
$cachedValue['uid'] = $uid;
$cachedValue['scope'] = 16; // 權(quán)限值,自己定義
return $cachedValue;
}
private function saveToCache($cachedValue) {
$key = self::generateToken(); // 生成令牌的方法
$value = json_encode($cachedValue);
$tokenExpire = config('setting.token_expire'); // 設(shè)定的過(guò)期時(shí)間
$request = cache($key, $value, $tokenExpire);
if (!$request) {
throw new TokenException([
'msg' => '服務(wù)器緩存異常',
'errorCode' => 10005
]);
}
return $key; // 返回令牌:token
}可以看到,核心流程就是:
拿到openid查看數(shù)據(jù)庫(kù),檢查openid是否已經(jīng)存在如果存在,不處理,反之則新增一條user記錄生成令牌,準(zhǔn)備緩存數(shù)據(jù),寫入緩存把令牌返回到客戶端去其中generateToken()這個(gè)方法詳細(xì)定義如下:
public static function generateToken() {
$randomChars = getRandomChars(32); // 32個(gè)字符組成一組隨機(jī)字符串
$timestamp = $_SERVER['REQUEST_TIME_FLOAT'];$salt = config('security.token_salt'); // salt 鹽
// 拼接三組字符串,進(jìn)行MD5加密,然后返回
return md5($randomChars.$timestamp.$salt);
}
function getRandomChars($length) {
$str = null;
$strPoll = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789';
$max = strlen($strPoll) - 1;
for ($i = 0; $i < $length; $i++) {
$str .= $strPoll[rand(0, $max)];
}
return $str;
}它的主要作用毫無(wú)疑問(wèn)就是生成我們的需要的令牌——Token字符串。值得一提的是由于generateToken()在其他類型的Token里也會(huì)用到,所以是放在Token基類里的。
至此,只需要把生成的令牌再返回到Controller就行了。
三、總結(jié)令牌的編寫涉及到很多的流程,為了避免混亂,一定要注意把負(fù)責(zé)不同工作的代碼分別定義在不同的方法里。就像上面例子里grantToken()方法體現(xiàn)的那樣,這是個(gè)核心方法,包含所有流程,但是不同的具體流程又定義在其他方法里,然后提供給grantToken()方法調(diào)用。
這樣做之后grantToken()方法即使包含所有流程,但也依然很容易閱讀。
當(dāng)前題目:php如何設(shè)置權(quán)限令牌token
文章網(wǎng)址:http://www.chinadenli.net/article0/cgggio.html
成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供做網(wǎng)站、Google、App設(shè)計(jì)、域名注冊(cè)、網(wǎng)站策劃、ChatGPT
聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請(qǐng)盡快告知,我們將會(huì)在第一時(shí)間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如需處理請(qǐng)聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時(shí)需注明來(lái)源: 創(chuàng)新互聯(lián)