這篇文章主要介紹php設(shè)置 token的方法,文中介紹的非常詳細(xì),具有一定的參考價值,感興趣的小伙伴們一定要看完!
創(chuàng)新互聯(lián)是一家朝氣蓬勃的網(wǎng)站建設(shè)公司。公司專注于為企業(yè)提供信息化建設(shè)解決方案。從事網(wǎng)站開發(fā),網(wǎng)站制作,網(wǎng)站設(shè)計,網(wǎng)站模板,微信公眾號開發(fā),軟件開發(fā),微信小程序開發(fā),10多年建站對石雕等多個方面,擁有多年的網(wǎng)站制作經(jīng)驗。php設(shè)置token的方法:首先定義獲取Token的路由路徑;然后建立Service層;接著在Model層里建立User類,并在驗證器類和異常類創(chuàng)建相應(yīng)的驗證方法和異常處理;最后完成Token令牌的編寫即可。
我們開發(fā)的后端API接口會對訪問者有一個權(quán)限要求,比如一些包含私人信息的接口,就需要訪問者請求接口的同時,傳遞一個提前已經(jīng)發(fā)放給訪問者的Token。
這就像一個令牌一樣,只有訪問者展示出來我們才會“通過放行”。
下面就記錄一下權(quán)限令牌的代碼編寫思路。
首先定義好路由路徑:
Route::post( 'api/:version/token/user', 'api/:version.Token/getToken');復(fù)制代碼
然后創(chuàng)建Token控制器,定義對應(yīng)路由路徑的getToken方法:
public function getToken($code='') { (new TokenGet())->goCheck($code); // 驗證器 $token = (new UserToken($code))->get(); return [ 'token' => $token ]; }復(fù)制代碼
在調(diào)用Service層之前,還得檢查一下傳遞過來的參數(shù),于是定義TokenGet這個驗證器:
class TokenGet extends BaseValidate { protected $rule = [ 'code' => 'require|isNotEmpty' ]; protected $message = [ 'code' => '需要code才能獲得Token!' ]; }復(fù)制代碼
回到Token控制器,驗證通過后,我們調(diào)用Service層定義的UserToken類:
$token = (new UserToken($code))->get();復(fù)制代碼
這里討論一下Service層和Model層。我們普遍的理解是Service層是基于Model層的一次抽象封裝。
但我覺得小項目的話,Service其實和Model就有點平級的意思,因為有些簡單的接口Model層直接對接Controller就可以了,只有相對復(fù)雜的接口,比如用戶權(quán)限,就可以再經(jīng)過Service層分隔不同功能的代碼。
這樣的處理更加靈活,有大量確實很簡單的接口就不用過一次Service層了,這樣更像是走過過場而已,沒什么意義了。
回到Service層的代碼編寫,由于Token還會有不同的種類,所以先創(chuàng)建一個Token基類,里面包含一些通用的方法。然后就是給訪問者返回令牌的UserToken類的編寫了。
由于是基于微信,我們需要三個信息:code,appid,appsecret,然后通過構(gòu)造函數(shù)來給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 ); }復(fù)制代碼
然后把這三個放入微信提供的接口的參數(shù)位置,目的是獲得一個完整的微信服務(wù)器端的url,請求到我們需要的openid。
然后是通過發(fā)送網(wǎng)絡(luò)請求的步驟就在此略過。微信服務(wù)器會返回包含openid的對象,判斷這個對象的值沒問題后,我們就開始生成令牌的步驟了,創(chuàng)建函數(shù)grantToken():
private function grantToken($openidObj) { // 取出openid $openid = $openidObj['openid']; // 通過Model層調(diào)用數(shù)據(jù)庫,檢查openid是否已經(jīng)存在 $user = UserModel::getByOpenID($openid); // 如果存在,不處理,反之則新增一條user記錄 if ($user) { $uid = $user->id; } else { // 不存在,生成一條數(shù)據(jù),具體方法略過 $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è)定的過期時間 $request = cache($key, $value, $tokenExpire); if (!$request) { throw new TokenException([ 'msg' => '服務(wù)器緩存異常', 'errorCode' => 10005 ]); } return $key; // 返回令牌:token }復(fù)制代碼
可以看到,核心流程就是:
其中generateToken()
這個方法詳細(xì)定義如下:
public static function generateToken() { $randomChars = getRandomChars(32); // 32個字符組成一組隨機字符串 $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; }復(fù)制代碼
它的主要作用毫無疑問就是生成我們的需要的令牌——Token字符串。值得一提的是由于generateToken()
在其他類型的Token里也會用到,所以是放在Token基類里的。
至此,只需要把生成的令牌再返回到Controller就行了。
令牌的編寫涉及到很多的流程,為了避免混亂,一定要注意把負(fù)責(zé)不同工作的代碼分別定義在不同的方法里。就像上面例子里grantToken()
方法體現(xiàn)的那樣,這是個核心方法,包含所有流程,但是不同的具體流程又定義在其他方法里,然后提供給grantToken()
方法調(diào)用。
這樣做之后grantToken()
方法即使包含所有流程,但也依然很容易閱讀。
以上是php設(shè)置 token的方法的所有內(nèi)容,感謝各位的閱讀!希望分享的內(nèi)容對大家有幫助,更多相關(guān)知識,歡迎關(guān)注創(chuàng)新互聯(lián)-成都網(wǎng)站建設(shè)公司行業(yè)資訊頻道!