梁 宏 ,魏 慶 ,劉子震 ,陳 凱
(1.開封大學(xué) a.繼續(xù)教育學(xué)院,b.圖書館,河南 開封 475004;2.河南財經(jīng)政法大學(xué) 計算機與信息工程學(xué)院,河南 鄭州 450046)
傳統(tǒng)的OA系統(tǒng)需要憑用戶名和密碼登錄,操作不太方便。改為微信掃碼登錄,既可避免每次都要輸入用戶名和密碼的繁瑣,又可提高賬戶的安全性[1]。因此,改造傳統(tǒng)OA的登錄機制,增加微信掃碼登錄功能,成為升級現(xiàn)有辦公系統(tǒng)的重要工作內(nèi)容之一。
關(guān)于實現(xiàn)微信掃碼登錄功能,目前的主流方案為:通過注冊微信開放平臺賬戶,獲得相應(yīng)接口的調(diào)用權(quán)限,調(diào)用指定的URL地址后,回調(diào)至指定頁面,從而完成掃碼登錄[2]。
微信開放平臺是一個與微信公眾號 (主要分為訂閱號、服務(wù)號、企業(yè)號三種類型,除訂閱號外,其他兩種類型都具有二次開發(fā)功能)并行的獨立系統(tǒng)平臺,用戶每年都需要額外付費注冊或認(rèn)證,方可使用,即便是擁有自己公眾號的機構(gòu),也不例外。
那么,能否通過單服務(wù)號完成微信掃碼登錄,而無須額外購買注冊微信開放平臺賬戶呢?答案是:可以。通過現(xiàn)有的微信公眾服務(wù)號,單獨實現(xiàn)微信掃碼登錄功能,可以有效提高傳統(tǒng)OA的升級改造效率,提高OA與用戶微信的融合度,并且可以免除額外注冊認(rèn)證的負(fù)擔(dān)。本文擬通過具體案例,探討這一功能的實現(xiàn)路徑。本文提供的設(shè)計方案對融合傳統(tǒng)OA與微信功能也具有一定的參考價值。
實現(xiàn)微信掃碼登錄的實質(zhì)就是對用戶身份進行鑒別。微信公眾號系統(tǒng)面對每一位關(guān)注該公號的人員,都會生成一個唯一的識別碼OpenID,這就相當(dāng)于給每位用戶分配一個“身份證號”,用戶取消關(guān)注后再次關(guān)注,這個號碼也保持不變[3][4]。
當(dāng)用戶通過電腦瀏覽器打開OA系統(tǒng)進行登錄的時候,系統(tǒng)會產(chǎn)生登錄二維碼。用戶拿手機微信掃描后,會被導(dǎo)入指定微信公眾號進行身份驗證。微信公眾號驗明用戶身份后,會向OA服務(wù)器“打招呼”放行,OA服務(wù)器將設(shè)置“已驗證”標(biāo)志。用戶的瀏覽器檢測到“已驗證”后,即轉(zhuǎn)向OA系統(tǒng)的主界面,從而完成微信掃碼登錄工作。
前面提到,微信公眾號需要給OA服務(wù)器 “打招呼”?;诖耍梢酝ㄟ^RPC或者數(shù)據(jù)庫等方式實現(xiàn)“狀態(tài)”傳遞。本案例采用的是MySQL云數(shù)據(jù)庫,以此實現(xiàn) “耦合”,完成數(shù)據(jù)交換。開發(fā)環(huán)境為Golang+beeGo框架。
為便于數(shù)據(jù)交換,在云數(shù)據(jù)庫中建表OA_Lo-gin。其結(jié)構(gòu)如圖1所示:
圖1 OA_Login表結(jié)構(gòu)
要在所有OA頁面的控制器基類中添加權(quán)限驗證,如無權(quán)限,就會被導(dǎo)向微信掃碼登錄界面。本案例在BaseController的Prepare方法中檢查會話變量ssOPENID是否為空,若為空,則轉(zhuǎn)向掃碼登錄界面。
在用戶通過瀏覽器加載時,即與云數(shù)據(jù)庫交互,通過 select replace(uuid(),'-','') as uuid;語句,產(chǎn)生無“-”符的UUID。UUID是較GUID更利于數(shù)據(jù)庫檢索的全局唯一性ID值,此ID值將被作為與用戶會話的憑據(jù),在產(chǎn)生二維碼圖案和進行身份核驗時發(fā)揮關(guān)鍵作用。之所以不采用數(shù)據(jù)庫自增型ID,是因為想讓輸出的二維碼圖案疏密度合適,盡量一致,并且由于位數(shù)長達32位,所以增強了安全性。將產(chǎn)生的UUID值插入OA_Login表,并將產(chǎn)生的時間值填寫進ITm(InsertTime)字段。每次刷新掃碼登錄界面時,都會往數(shù)據(jù)表中插入新的UUID。為防止數(shù)據(jù)表無限制擴大,在每次產(chǎn)生新值前,都會將產(chǎn)生時間超過60s的值予以刪除。將此UUID和生成時間加密,與微信公眾號服務(wù)器訪問URL拼接成字符串,將此字符串生成二維碼圖片。為了保證瀏覽器每次刷新頁面時都重新加載圖片,我們采用添加“version=不重復(fù)的隨機值”參數(shù)的形式,如:
在此頁面加載完成后,插入定時檢測函數(shù):
此函數(shù),每隔2.5s,在用戶無感知的情況下,都會向OA服務(wù)器進行AJAX查詢。一旦查詢到后臺返回數(shù)據(jù),即重新定向到OA主界面。
用戶用手機微信掃描二維碼后,將連帶上述UUID、ITM值被導(dǎo)向本單位微信公眾號服務(wù)器的特定驗證頁面。
增加此專用頁面,用來接收上步傳來的參數(shù)。此頁面調(diào)用微信服務(wù)號接口scope,為snsapi_userinfo獲取用戶OpenID,同時解密UUID和ITM參數(shù)。對于新OpenID,轉(zhuǎn)向新用戶注冊申請界面,要求填寫用戶名和身份證號,從而完成OpenID與操作員的綁定。如圖2所示:
圖2 新用戶注冊界面
綁定的用戶要經(jīng)管理員后臺授權(quán)。以后再次掃碼登錄,就會出現(xiàn)如圖3所示的界面。
圖3 確認(rèn)登錄界面
用戶在手機端按下“確定登錄”鍵后,微信公眾號服務(wù)器將向云數(shù)據(jù)庫OA_Login表中鍵值為收到的UUID的記錄寫入此用戶的OpenID。
在此步驟中,將解密的ITM時間和當(dāng)前時間值放在一起比較,超過60s的,將被視為超時報錯,要求用戶重新掃碼操作。
事實上,在掃碼登錄界面的請求下,OA服務(wù)器會定時查詢 OA_Login表中鍵值為此 UUID的OpenID字段值,一旦字段值不再為空,即設(shè)置會話變量ssOPENID=OpenID,同時返回“OK”狀態(tài)碼給掃碼登錄界面。掃碼登錄界面AJAX定時查詢到此信號后,重定向到OA主界面,從而完成掃碼登錄,全過程結(jié)束。
通過對OA服務(wù)器進行升級改造,實現(xiàn)了它與微信公眾號服務(wù)器的“溝通協(xié)調(diào)”,實現(xiàn)了老OA系統(tǒng)的微信掃碼登錄功能,特別是通過單微信公眾服務(wù)號,完成了OpenID獲取和用戶身份驗證,避免了重復(fù)購買微信開放平臺。同時,微信公眾服務(wù)號所擁有的OAuth2.0具備高安全性,這也使原OA系統(tǒng)的安全性得到了更好的保障。
由于建立起OA系統(tǒng)與微信公眾服務(wù)號之間的聯(lián)系,特別是拿到了OpenID,所以一些智能化的信息推送成為可能,如向用戶手機微信推送文件簽批進展情況、工資發(fā)放通知等,這是采用這一設(shè)計方案的又一額外收獲。