搜尋
首頁後端開發PHP問題php如何設定權限令牌token

php如何設定權限令牌token

Aug 20, 2020 am 10:13 AM
phptoken

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

php如何設定權限令牌token

推薦:《PHP影片教學

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的詳細內容。更多資訊請關注PHP中文網其他相關文章!

陳述
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn

熱AI工具

Undresser.AI Undress

Undresser.AI Undress

人工智慧驅動的應用程序,用於創建逼真的裸體照片

AI Clothes Remover

AI Clothes Remover

用於從照片中去除衣服的線上人工智慧工具。

Undress AI Tool

Undress AI Tool

免費脫衣圖片

Clothoff.io

Clothoff.io

AI脫衣器

Video Face Swap

Video Face Swap

使用我們完全免費的人工智慧換臉工具,輕鬆在任何影片中換臉!

熱門文章

熱工具

Dreamweaver CS6

Dreamweaver CS6

視覺化網頁開發工具

Atom編輯器mac版下載

Atom編輯器mac版下載

最受歡迎的的開源編輯器

mPDF

mPDF

mPDF是一個PHP庫,可以從UTF-8編碼的HTML產生PDF檔案。原作者Ian Back編寫mPDF以從他的網站上「即時」輸出PDF文件,並處理不同的語言。與原始腳本如HTML2FPDF相比,它的速度較慢,並且在使用Unicode字體時產生的檔案較大,但支援CSS樣式等,並進行了大量增強。支援幾乎所有語言,包括RTL(阿拉伯語和希伯來語)和CJK(中日韓)。支援嵌套的區塊級元素(如P、DIV),

Dreamweaver Mac版

Dreamweaver Mac版

視覺化網頁開發工具

禪工作室 13.0.1

禪工作室 13.0.1

強大的PHP整合開發環境