微信小程序 服務器端生成用戶登陸環節的 3rd_session


一、環境:

CentOS 6.8
nginx 1.8.0
php 7.0.10

二、背景

最近在開發一個微信小程序,不可避免的涉及到登陸的環節,登錄時序圖如下:

通過 wx.login() 獲取到用戶登錄態之后,需要維護登錄態。開發者要注意不應該直接把 session_key、openid 等字段作為用戶的標識或者 session 的標識,而應該自己派發一個session 登錄態
—— 微信官方文檔(https://mp.weixin.qq.com/debug/wxadoc/dev/api/api-login.html#wxchecksessionobject)

所以,我們要給服務器上的 session 登錄態設定一個 key 值,key 值就是本文說的 3rd_session

三、正文

下面就是生成 3rd_session 的方法了,具體代碼的解釋可以看注釋和上文的登錄時序圖對 3rd_session 的要求,就不贅述了。

    function _3rd_session($len)
    {

        $fp = @fopen('/dev/urandom', 'rb');

        $result = '';

        if ($fp !== FALSE) {

            $result .= @fread($fp, $len);

            @fclose($fp);

        } else {

            trigger_error('Can not open /dev/urandom.'); 

        }

        // convert from binary to string

        $result = base64_encode($result);

        // remove none url chars

        $result = strtr($result, '+/', '-_');


        return substr($result, 0, $len);

    }

    echo _3rd_session(16);

四、遇到的問題

1、@fopen('/dev/urandom', 'rb') 的時候,報錯 "Can not open /dev/urandom"

說明 fopen('/dev/urandom', 'rb') 沒有成功打開文件,一般有三種原因:

1、路徑不對
2、文件不存在
3、沒有權限

1/2、路徑不對 /文件不存在

如果 /dev/ 里沒有 urandomrandom 文件(必須兩者同時存在),可以用下面方法生成這兩個文件:

 mknod -m 644 /dev/random c 1 8
 mknod -m 644 /dev/urandom c 1 9
 chown root:root /dev/random /dev/urandom
3、沒有權限

如果有這兩個文件存在,且你的接口所在項目的權限也沒問題的時候,可能是 php 的訪問權限造成的:

open_basedir 是 控制 php 訪問路徑權限的屬性。

我查看了我的 php.ini,果然沒有包含 /dev/

image.png

於是我修改了 php.iniopen_basedir 值,並重啟了 php:

service php-fpm restart

再次打開 php.ini,哪尼? open_basedir 的值根本沒變。

原來,是 nginx 的設置插了一腳。

在 nginx 的 nginx.conf 中的某個 server 中:

       location ~ \.php($|/) {
            fastcgi_pass   unix:/dev/shm/php-cgi.sock;
            fastcgi_index  index.php;
            fastcgi_split_path_info ^(.+\.php)(.*)$;
            fastcgi_param   PATH_INFO $fastcgi_path_info;
            fastcgi_param  PHP_VALUE  "open_basedir=$document_root:/tmp/";
                        include        fastcgi_params;
            fastcgi_param  SCRIPT_FILENAME  $document_root$fastcgi_script_name;
        }

把倒數第三行中的 open_basedir 添加上 /dev/ 路徑,即為:

fastcgi_param  PHP_VALUE  "open_basedir=$document_root:/tmp/:/dev/";

完美。

五、知識點

(1)為什么在 '/dev/urandom' 里取隨機數?

微信的官方文檔推薦用這種操作系統提供真正隨機數的方法。而不是
srand(當前時間) 然后 rand() 的方法。

(2)'/dev/urandom' 是真的隨機數?

其實絕對隨機的隨機數只是一種理想的隨機數,即使計算機怎樣發展,它也不會產生一串絕對隨機的隨機數。

但是 '/dev/urandom' 和 '/dev/random' 已經算是很接近真隨機數的隨機數了。

他們的原理是,數據通常來自於設備驅動程序。例如,鍵盤驅動程序收集兩個按鍵之間時間的信息,然后將這個環境噪聲填入隨機數發生器庫。

linux 內核維護了一個熵池用來收集來自設備驅動程序和其它來源的環境噪音,它在每次有新數據進入時進行“攪拌” 。使得更隨機。

(3)'/dev/random' 和 '/dev/urandom' 有什么區別?

因為熵池中返回的隨機數依賴於外部,'/dev/random' 往往被取出過快導致熵池里沒有剩余可用的隨機數。

但是 '/dev/urandom' 仍可以從熵池的 MD5 散列中獲得非常好的隨機數,所以為了程序的健壯性,推薦使用 '/dev/urandom'。

但是 '/dev/random' 會比 '/dev/urandom' 安全,因為后者依賴MD5,會存在被破譯的風險。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM