Winform混合式開發框架訪問Web API接口的處理

在個人混合式開發框架裏面,集成了WebAPI的訪問,這種訪問方式不只能夠實現簡便的數據交換,並且能夠在多種平臺上進行接入,如Winform程序、Web網站、移動端APP等多種接入方式,Web API的處理方式和微信提供的接口處理規則相似,也是經過向服務器得到訪問令牌(AccessToken),而後傳遞給每一個Web API接口,實現數據的交換處理。本篇隨筆主要介紹混合框架中Winform對Web API訪問的處理。html

一、Web API接入方式介紹

《混合式開發框架》混合了Web API接口訪問、WCF接口訪問,以及直接訪問數據庫三種方式的接入,以適應多種場景的應用,是基於門面層的一種接口實現處理和封裝。是一種彈性化很是好的框架應用,既可用於單機版軟件或者基於局域網內的應用軟件,也能夠用於分佈式技術的互聯網環境應用,是一種成熟穩定、安全高效的技術框架。數據庫

關於這個框架的詳細介紹,能夠查看個人隨筆《Winform混合式開發框架的特色總結》進行詳細瞭解。api

這裏主要關注Web API的接入方式,咱們知道,若是是通常的接口,若是公佈在互聯網上面,就會有不少接入的風險,所以須要對接口的調用進行檢查校驗,確保訪問令牌有效,並且對數據發生修改的,還須要對數據的加密簽名進行檢查,才能保證咱們的接口運行在較爲安全的環境中。瀏覽器

混合框架調用Web API接口的詳細過程,能夠經過《Web API應用架構在Winform混合框架中的應用(3)--Winfrom界面調用WebAPI的過程分解》、《Web API應用架構在Winform混合框架中的應用(1)》、《Web API接口設計經驗總結》進行了解。緩存

二、Web API的接口訪問令牌的處理

因爲咱們須要對接口訪問的身份進行覈實,所以通常要求咱們的接口都帶有一個token參數,用來對用戶身份進行識別,以下所示是Web API層的MVC控制器的接口定義。安全

        [HttpGet]
        public UserInfo GetUserByName(string userName, string token)
        {
            //令牌檢查,不經過則拋出異常
            CheckResult checkResult = CheckToken(token);

            return BLLFactory<User>.Instance.GetUserByName(userName);
        }

若是咱們在客戶端須要調用這個接口,那麼就須要傳入這個token參數,也就是說這個token令牌須要在調用任何接口前得到,這樣才能爲咱們後面的接口調用作好準備。服務器

而這個token的產生是很是重要的,須要嚴格頒發,所以須要對獲取這個token的方法的參數進行簽名校驗,以下面代碼是WebAPI接口對產生token的處理。微信

        /// <summary>
        /// 註冊用戶獲取訪問令牌接口
        /// </summary>
        /// <param name="username">用戶登陸名稱</param>
        /// <param name="password">用戶密碼</param>
        /// <param name="signature">加密簽名字符串</param>
        /// <param name="timestamp">時間戳</param>
        /// <param name="nonce">隨機數</param>
        /// <param name="appid">應用接入ID</param>
        [HttpGet]
        public TokenResult GetAccessToken(string username, string password, string signature, string timestamp, string nonce, string appid)

也就是須要傳入用戶名、密碼、加密簽名、時間戳、隨機數、應用接入ID等信息,從而構建出來一個訪問令牌,經過用戶名、密碼、加密簽名校驗等方式,能夠實現對訪問令牌(token)的嚴格頒發處理。架構

在客戶端調用全部Web API接口前,咱們須要先經過上面的Web API接口,獲取到該用戶的訪問令牌,爲了方便,咱們能夠在客戶端封裝一個函數,經過這個函數獲取到對應的訪問令牌,而後把它存儲在緩存裏面,方便各個模塊的接口訪問處理。app

    /// <summary>
    /// 用戶獲取令牌的輔助類
    /// </summary>
    public class AccessTokenHelper
    {
        private const string APPID = "APPID";//應用ID,由系統管理員分配
        private const string APPSECRET = "APPSECRET";//應用祕鑰,,由系統管理員分配
        private const string DEFAULT_API_URL = "http://localhost:9001/api/Auth/GetAccessToken";//默認調試的Web API獲取受權地址

        /// <summary>
        /// 設置簽名參數。
        /// 因爲Web API大多數的接口,都須要驗證用戶身份的訪問令牌(accesstoken),所以用戶在登錄的時候,須要使用這個步驟去獲取令牌信息,而後在繼續後續的接口操做。
        /// 該接口用到的應用ID、應用祕鑰等參數,由系統管理員統一分配。
        /// </summary>
        public static bool GetAccessToken(string username, string password)
        {
            bool result = false;

            //配置使用Web API模式,須要構建登錄token才能訪問
            AppConfig config = new AppConfig();
            string callerType = config.AppConfigGet("CallerType");
            string apiUrl = config.AppConfigGet("AuthApiUrl");
            apiUrl = string.IsNullOrEmpty(apiUrl) ? DEFAULT_API_URL : apiUrl;

            if (callerType.Equals("api", StringComparison.OrdinalIgnoreCase))
            {
                //使用API方式,須要在緩存裏面設置特殊的信息
                var url = apiUrl + SignatureHelper.GetSignatureUrl(APPID, APPSECRET);
                url += string.Format("&username={0}&password={1}", username, password);

                TokenResult tokenResult = JsonHelper<TokenResult>.ConvertJson(url);
                result = !string.IsNullOrEmpty(tokenResult.access_token);

                if (tokenResult == null)
                {
                    var message = "獲取受權信息出錯,請檢查地址是否正確!";
                    MessageDxUtil.ShowError(message);
                }

                var SignatureInfo = new SignatureInfo()
                {
                    appid = APPID,
                    appsecret = APPSECRET,
                    token = (tokenResult != null) ? tokenResult.access_token : null
                };
                Cache.Instance.Add("SignatureInfo", SignatureInfo);
            }

            return result;
        }

有了這個輔助方法,咱們能夠在程序啓動後,用戶進行身份登陸的時候,先調用這個方法來獲取令牌。

                string ip = NetworkUtil.GetLocalIP();
                string macAddr = HardwareInfoHelper.GetMacAddress();
                string loginName = this.txtLoginName.Text.Trim();
                string password = this.txtPassword.Text;

                //若是沒法獲取訪問令牌,則返回
                bool hasGotToken = AccessTokenHelper.GetAccessToken(loginName, password);
                if (!hasGotToken)
                {
                    return;
                }

 

剛纔我提到了Web API層的MVC控制器的接口定義,默認後面通常都有一個token參數,以下代碼所示

        [HttpGet]
        public UserInfo GetUserByName(string userName, string token)
        {
            //令牌檢查,不經過則拋出異常
            CheckResult checkResult = CheckToken(token);

            return BLLFactory<User>.Instance.GetUserByName(userName);
        }

而咱們爲了方便客戶端調用,通常在客戶端調用Web API的時候進行簡化了一下,把token參數拿掉,它的值從緩存裏面提取。如客戶端調用的封裝代碼以下所示。

        public UserInfo GetUserByName(string userName)
        {
            var action = "GetUserByName";
            string url = GetTokenUrl(action) + string.Format("&userName={0}", userName);

            UserInfo result = JsonHelper<UserInfo>.ConvertJson(url);
            return result;
        }

其中GetTokenUrl就是咱們根據token和方法名稱,構建一個鏈接字符串,函數實現以下所示。

        /// <summary>
        /// 獲取單純包含token參數的鏈接
        /// </summary>
        /// <param name="action">控制器方法名稱</param>
        /// <returns></returns>
        protected string GetTokenUrl(string action)
        {
            string url = "";
            if (this.SignatureInfo != null)
            {
                var append = string.Format("?token={0}", SignatureInfo.token);

                string baseUrl = GetBaseUrl();
                url = CombindUrl(baseUrl, action + append);//組合爲完整的訪問地址
            }
            else
            {
                throw new ArgumentNullException("沒有在緩存裏面設置SignatureInfo簽名信息");
            }
            return url;
        }

這樣最終咱們能夠得到相似下面的鏈接地址:

http://localhost:27206/api/Account/GetAccountTypeList?token=eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpc3MiOiIxIiwiaWF0IjoxNDYzNTU3OTAzLCJqdGkiOiI3OGMyOGRhNC01ZjRjLTQxYzItOThkNC1lYmFkZTM3YjA4NjUiLCJuYW1lIjoiYWRtaW4iLCJjaGFubmVsIjoiMCIsInNoYXJlZGtleSI6IjEyMzRhYmNkIn0.DysdbGx70xuIxXBz3G3x3MkGh9ZxL2zF9Fzu8FGVS0w

有了這個令牌組裝好的URL,咱們能夠對訪問結果的JSON字符串進行解析,把它解析爲對應的數據就能夠了。

固然,在實際的Web API接口開發過程當中,咱們還可使用Web API工具進行接口調試,以下所示。

下面的1-5的標識就是獲取token所須要的簽名數據,固然鏈接還帶有幾個帳號認證所須要的信息了,如帳號密碼、所在公司等信息。

固然咱們也可使用瀏覽器進行測試獲取Token的信息,只是沒有那麼方便而已。

相關文章
相關標籤/搜索