鍍金池/ 問答/PHP/ php 控制權限問題

php 控制權限問題

同一時間內 只限五個人來訪問 其他人進不來 進來的這五個人只有一分鐘的控制權 到時間自動銷毀權限 期間還要防止用戶惡意刷新 大神們有沒有相關的demo 學習一下

例如:用戶進入一個web界面,點擊界面上的按鈕,假如用戶量很多,只限制五六個人可以得到按鈕的控制權發(fā)送信息,這五六個人有一分鐘的時間玩 過了一分鐘后,他們就丟失控制權,其他用戶可以獲得控制權,歡迎各位大神給個相對應的demo 學習一下 給以私信我 領個紅包

回答
編輯回答
別逞強
  1. 在點擊按鈕后,給有權限的人分配一個Token,并將該Token 記錄到緩存中,設置為 1分鐘過期.
    操作:

    用戶點擊進入按鈕的時候, 判斷當前擁有權限的人數(shù)是否達到閥值 (判斷Token的數(shù)量)
    達到閥值,然會403 Forbidden. 否則生成新的Token 分配給該用戶
    
  2. 將該Token 發(fā)送給前端, 后續(xù)有限制的操作都要求客戶端將 Token回傳給服務器. 交由服務器嚴重Token 的有效性, 有效才能訪問,否則不可以訪問.

大致邏輯應該是這樣的.僅供參考.

這個代碼肯定是跑不起來的哦.不過思路應該就這樣了

<?php

// 除了 Auth 可以匿名訪問(就是客戶端請求的時候,不帶Token的情況)之外. 其他的所有請求都必須攜帶Token上傳
// 這里的Token 可以放到 Header 中
$request = HttpRequest;
$response = HttpResponse();
// 請求資源不是Auth,且沒有攜帶Token的情況,直接返回403,或者跳轉頁面到獲取Token的地方(就是點擊進入頁面的那個按鈕的地方)
if ($request->getPath() !== 'auth' && !$request->getHeader('token')) {
    return $response->withHeader(403);
}

// 如果攜帶Token,但是Token已經失效,那么不能訪問,或者跳轉到獲取Token頁面重新獲取Token
if ($token = $request->getHeader('token') && !(new Accessable($token))->isTokenAvaliable()) {
    return $response->withHeader(403); 
}

// 正常邏輯

/*****************************************************************************************/

class Accessable()
{
    protected $token;
    
    public function __construct($token)
    {
        $this->token = $token;
    }
    
    /**
     * 老用戶是否還有權限可以訪問,就是判斷他的Token是否還存在,畢竟1分鐘后,Token就會自動被刪除
     */
    public function isTokenAvaliable()
    {
        $redis = Redis();
        if ($redis->exists($token)) {
            return true;
        }
        
        return false;
    }
}

/**
 * 授權操作
 */
class Auth
{
    const EXPIRE_TIME = 60;
    const AUTH_TOKENS = 'auth_tokens';    // 用來保存所有的Token,方便Redis查詢
    
    public function POST()
    {
        if (!$this->isNewUserAvaliable()) {
            return 403; // 返回403 Forbidden
        }

        $token = $this->generateToken();
        
        return $token;
    }
        
    /**
     * 生成可以訪問的票據(jù)Token
     */
    protected function generateToken()
    {
        $redis = new Redis();
        $token = sprintf('Token:%s', uuid());
        $redis->set($token, 1);
        $redis->expire($token, self::EXPIRE_TIME);     // 設置為1分鐘自動過期
        $redis->sAdd(self::AUTH_TOKENS, $token);
        
        return $token;
    }
    
    /**
     * 對于新用戶是否可以訪問判斷(因為他沒有攜帶Token上來,那么就是新用戶)
     * 判斷方式,是查詢Redis中存在的Token數(shù)量是否達到閥值
     */
    protected function isNewUserAvaliable()
    {
        $redis = new Redis();
        $tokens = $redis->sMembers(self::AUTH_TOKENS);
        $counter = 0;
        foreach ($tokens as $token) {
            if ($redis->exists($token)) {
                ++$counter;
                continue;
            }
            
            $redis->sRem($token);
        }
        
        if ($counter >= self::MAX_USER_COUNT) {
            return false;
        }
        
        return true;
    }
}




2018年5月9日 13:09
編輯回答
爆扎

1,根據(jù)字段狀態(tài),來判斷當前登陸用戶幾人
2,根據(jù)登陸時間開始計時,1分鐘自動token過期
3,惡意刷新,還沒想好。
希望能看到其他大神的精彩回答,

2018年3月2日 03:01
編輯回答
使勁操

基本上就是二樓的這種思路了。

2018年8月4日 18:02
編輯回答
萢萢糖

我覺得你們說的只能是當用戶進去后執(zhí)行操作,程序才會判斷,但是當用戶進去什么都不干的時候,程序就不會被啟動,需要你一遍又一遍的去用ajax刷新頁面提交給程序判斷,這樣肯定不科學。而且你們的糾結點都在判斷是否有權限那里,我始終覺得問題的核心在于那1分鐘內如果用戶不操作程序,怎么讓程序知道這個人是否已經過期。但是我個人功力有限,提出了想法卻沒想到解決思路,盼大神指點。

2018年2月4日 16:36