中文字幕av专区_日韩电影在线播放_精品国产精品久久一区免费式_av在线免费观看网站

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

php設置權限令牌token的方法

發布時間:2020-08-21 10:41:49 來源:億速云 閱讀:274 作者:小新 欄目:編程語言

這篇文章主要介紹了php設置權限令牌token的方法,具有一定借鑒價值,需要的朋友可以參考下。希望大家閱讀完這篇文章后大有收獲。下面讓小編帶著大家一起了解一下。

php設置token的方法:1、定義獲取Token的路由路徑;2、建立Service層;3、使用UserToken類處理整個邏輯;4、在Model層里建立User類;5、在驗證器類和異常類創建相應的驗證方法和異常處理。

php設置權限令牌token的方法

PHP_設置權限令牌Token

我們開發的后端API接口會對訪問者有一個權限要求,比如一些包含私人信息的接口,就需要訪問者請求接口的同時,傳遞一個提前已經發放給訪問者的Token。

這就像一個令牌一樣,只有訪問者展示出來我們才會“通過放行”。

下面就記錄一下權限令牌的代碼編寫思路。


一、流程概要

  • 定義獲取Token的路由路徑,接受code參數(code來源:微信服務器,登錄系統基于微信體系)

  • 建立Service層,在這層里創建Token基類和UserToken類

  • UserToken類處理整個邏輯:Token生成和返回

  • 在Model層里建立User類,負責用戶數據表的讀寫,供Service層的UserToken調用

  • 在驗證器類和異常類創建相應的驗證方法和異常處理

  • 控制器->Service層->Model層返回值給Service層->Service層返回值給控制器,整個流程完成Token令牌的編寫

二、具體說明

首先定義好路由路徑:

Route::post(
    'api/:version/token/user',
    'api/:version.Token/getToken'
);

然后創建Token控制器,定義對應路由路徑的getToken方法:

public function getToken($code='') {
        (new TokenGet())->goCheck($code); // 驗證器
        $token = (new UserToken($code))->get();
        return [
            'token' => $token
        ];
    }

在調用Service層之前,還得檢查一下傳遞過來的參數,于是定義TokenGet這個驗證器:

class TokenGet extends BaseValidate
{
    protected $rule = [
      'code' => 'require|isNotEmpty'
    ];

    protected $message = [
        'code' => '需要code才能獲得Token!'
    ];
 }

回到Token控制器,驗證通過后,我們調用Service層定義的UserToken類:

$token = (new UserToken($code))->get();復制代碼

這里討論一下Service層和Model層。我們普遍的理解是Service層是基于Model層的一次抽象封裝。

  • Model層只負責操作數據庫并返且返回給Service層
  • 然后Service層處理業務邏輯,最后返回給Controller層

但我覺得小項目的話,Service其實和Model就有點平級的意思,因為有些簡單的接口Model層直接對接Controller就可以了,只有相對復雜的接口,比如用戶權限,就可以再經過Service層分隔不同功能的代碼。

這樣的處理更加靈活,有大量確實很簡單的接口就不用過一次Service層了,這樣更像是走過過場而已,沒什么意義了。

回到Service層的代碼編寫,由于Token還會有不同的種類,所以先創建一個Token基類,里面包含一些通用的方法。然后就是給訪問者返回令牌的UserToken類的編寫了。

由于是基于微信,我們需要三個信息:code,appid,appsecret,然后通過構造函數來給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
    );
    }

然后把這三個放入微信提供的接口的參數位置,目的是獲得一個完整的微信服務器端的url,請求到我們需要的openid。

然后是通過發送網絡請求的步驟就在此略過。微信服務器會返回包含openid的對象,判斷這個對象的值沒問題后,我們就開始生成令牌的步驟了,創建函數grantToken():

private function grantToken($openidObj) {

        // 取出openid
        $openid = $openidObj['openid'];
        
        // 通過Model層調用數據庫,檢查openid是否已經存在
        $user = UserModel::getByOpenID($openid);
        
        // 如果存在,不處理,反之則新增一條user記錄
        if ($user) {
            $uid = $user->id;
        } else {
            // 不存在,生成一條數據,具體方法略過
            $uid = $this->newUser($openid); 
        }
        
        // 生成令牌,寫入緩存(具體方法見下面的定義)
        $cachedValue = $this->prepareCacheValue($openidObj, $uid);
        $token = $this->saveToCache($cachedValue);
        
        // 令牌返回到調用者端
        return $token;
}

private function prepareCacheValue($openidObj, $uid) {
    $cachedValue = $openidObj;
    $cachedValue['uid'] = $uid;
    $cachedValue['scope'] = 16; // 權限值,自己定義
    return $cachedValue;
}
    
private function saveToCache($cachedValue) {
    $key = self::generateToken(); // 生成令牌的方法
    $value = json_encode($cachedValue);
    $tokenExpire = config('setting.token_expire'); // 設定的過期時間

    $request = cache($key, $value, $tokenExpire);
        if (!$request) {
            throw new TokenException([
            'msg' => '服務器緩存異常',
            'errorCode' => 10005
        ]);
    }
    return $key; // 返回令牌:token
}

可以看到,核心流程就是:

  • 拿到openid
  • 查看數據庫,檢查openid是否已經存在
  • 如果存在,不處理,反之則新增一條user記錄
  • 生成令牌,準備緩存數據,寫入緩存
  • 把令牌返回到客戶端去

其中generateToken()這個方法詳細定義如下:

public static function generateToken() {
    $randomChars = getRandomChars(32); // 32個字符組成一組隨機字符串
    $timestamp = $_SERVER['REQUEST_TIME_FLOAT'];  
    $salt = config('security.token_salt'); // salt 鹽
    // 拼接三組字符串,進行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;
}

它的主要作用毫無疑問就是生成我們的需要的令牌——Token字符串。值得一提的是由于generateToken()在其他類型的Token里也會用到,所以是放在Token基類里的。

至此,只需要把生成的令牌再返回到Controller就行了。

三、總結

令牌的編寫涉及到很多的流程,為了避免混亂,一定要注意把負責不同工作的代碼分別定義在不同的方法里。就像上面例子里grantToken()方法體現的那樣,這是個核心方法,包含所有流程,但是不同的具體流程又定義在其他方法里,然后提供給grantToken()方法調用。

這樣做之后grantToken()方法即使包含所有流程,但也依然很容易閱讀。

感謝你能夠認真閱讀完這篇文章,希望小編分享php設置權限令牌token的方法內容對大家有幫助,同時也希望大家多多支持億速云,關注億速云行業資訊頻道,遇到問題就找億速云,詳細的解決方法等著你來學習!

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

抚松县| 哈巴河县| 乐都县| 绥中县| 鹤壁市| 噶尔县| 云龙县| 丁青县| 始兴县| 桂林市| 南平市| 准格尔旗| 博客| 鲁山县| 罗城| 靖安县| 周至县| 闻喜县| 项城市| 六枝特区| 安图县| 石首市| 仪陇县| 探索| 容城县| 阜南县| 界首市| 临朐县| 体育| 福泉市| 盐源县| 商河县| 南康市| 漾濞| 攀枝花市| 彭阳县| 汝阳县| 桦川县| 吉木萨尔县| 宁武县| 屯昌县|