首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> .NET 網頁程式設計 >> 關於.NET

Windows 8 市集應用程式開發實戰 (61):HTTP 通訊與 OAuth 2.0 驗證實作

     編輯:關於.NET

前言:現代應用程式的網路互動基石

HTTP 仍是行動應用程式與後端服務溝通的主流協定。Windows 8 提供 System.Net.Http.HttpClient 作為現代化、非同步優先的 HTTP 用戶端 API,支援 GET/POST/PUT/DELETE、串流處理、取消機制與標頭控制。本文並示範如何整合 OAuth 2.0 流程,呼叫新浪微博開放平台 API 取得使用者好友動態。

伺服器端測試端點 (HttpDemo.aspx)

簡單的 ASP.NET Web Form 根據 action 參數回應不同情境:

  • getString:回傳純文字
  • getStream:回傳長字串模擬串流
  • postString:回傳表單參數與 Referrer
  • postStream:回傳請求本體內容

並刻意 Thread.Sleep(3000) 模擬網路延遲,方便測試取消功能。

HttpClient 核心類別速覽

類別關鍵成員用途
HttpClientBaseAddress, DefaultRequestHeaders, Timeout, CancelPendingRequests(), GetAsync, PostAsync...發送請求、接收回應的主要進入點
HttpRequestMessageMethod, RequestUri, Headers, Content封裝單一 HTTP 請求
HttpResponseMessageStatusCode, ReasonPhrase, Headers, Content, EnsureSuccessStatusCode()封裝 HTTP 回應
HttpContent 衍生類別StringContent, ByteArrayContent, StreamContent, FormUrlEncodedContent請求/回應本體的不同表示形式

範例一:完整 HttpRequestMessage/ResponseMessage 流程

private async void btnPost_Click_1(object sender, RoutedEventArgs e) {
    _httpClient = new HttpClient();
    try {
        string url = "https://localhost:39629/HttpDemo.aspx?action=postString";
        var request = new HttpRequestMessage(HttpMethod.Post, url);
        request.Content = new FormUrlEncodedContent(new[] {
            new KeyValuePair("param1", "web"),
            new KeyValuePair("param2", "abcd")
        });
        request.Headers.Referrer = new Uri("https://webabcd.cnblogs.com");
        HttpResponseMessage response = await _httpClient.SendAsync(request);
        lblMsg.Text += (int)response.StatusCode + " " + response.ReasonPhrase + Environment.NewLine;
        lblMsg.Text += await response.Content.ReadAsStringAsync() + Environment.NewLine;
    } catch (TaskCanceledException) { /* 取消處理 */ }
    catch (Exception ex) { /* 錯誤處理 */ }
}

範例二:GET 字串與串流處理

GetString - 簡單字串取得

HttpResponseMessage response = await _httpClient.GetAsync(new Uri("...action=getString"));
lblMsg.Text += await response.Content.ReadAsStringAsync();

GetStream - 串流式讀取大量資料

關鍵在於 HttpCompletionOption.ResponseHeadersRead,讓 GetAsync 在收到標頭即返回,隨後以 ReadAsStreamAsync() 逐塊讀取:

HttpResponseMessage response = await _httpClient.GetAsync(uri, HttpCompletionOption.ResponseHeadersRead);
using (Stream responseStream = await response.Content.ReadAsStreamAsync()) {
    byte[] buffer = new byte[32];
    int read;
    while ((read = await responseStream.ReadAsync(buffer, 0, buffer.Length)) > 0) {
        // 處理 buffer,例如顯示十六進位
    }
}

範例三:POST 表單與串流上傳

PostString - 表單資料

var postData = new FormUrlEncodedContent(new[] {
    new KeyValuePair("param1", "web"),
    new KeyValuePair("param2", "abcd")
});
HttpResponseMessage response = await _httpClient.PostAsync(uri, postData);

PostStream - 二進位串流上傳

Stream stream = GenerateSampleStream(128); // 產生 128 bytes 測試資料
StreamContent streamContent = new StreamContent(stream);
HttpResponseMessage response = await _httpClient.PostAsync(uri, streamContent);

範例四:OAuth 2.0 用戶端實作 - 串接新浪微博

協定流程圖解

+--------+                               +---------------+
|        |--(A)- Authorization Request ->|   Resource    |
|        |                               |     Owner     |
|        |<-(B)-- Authorization Grant ---|               |
|        |                               +---------------+
|        |
|        |                               +---------------+
|        |--(C)-- Authorization Grant ->| Authorization |
| Client |                               |    Server     |
|        |<-(D)----- Access Token -------|               |
|        |                               +---------------+
|        |
|        |                               +---------------+
|        |--(E)----- Access Token ------>|   Resource    |
|        |                               |    Server     |
|        |<-(F)--- Protected Resource ---|               |
+--------+                               +---------------+

三步驟程式碼實作

  1. 取得 Authorization Code:使用 WebAuthenticationBroker.AuthenticateAsync 彈出系統級登入介面,無縫整合第三方 OAuth 頁面。
    var requestUrl = string.Format("https://api.weibo.com/oauth2/authorize?client_id={0}&response_type=code&redirect_uri={1}", appKey, callbackUrl);
    WebAuthenticationResult result = await WebAuthenticationBroker.AuthenticateAsync(
        WebAuthenticationOptions.None, new Uri(requestUrl), new Uri(callbackUrl));
    var authorizationCode = QueryString(result.ResponseData, "code");
  2. 換取 Access Token:以 Authorization Code 向 Token Endpoint 發送 POST 請求。
    var tokenUrl = string.Format("https://api.weibo.com/oauth2/access_token?client_id={0}&client_secret={1}&grant_type=authorization_code&redirect_uri={2}&code={3}", ...);
    HttpClient client = new HttpClient();
    var response = await client.PostAsync(new Uri(tokenUrl), null);
    var json = await response.Content.ReadAsStringAsync();
    var accessToken = JsonObject.Parse(json)["access_token"].GetString();
  3. 呼叫受保護資源:攜帶 Access Token 存取 API。
    var apiUrl = string.Format("https://api.weibo.com/2/statuses/friends_timeline.json?access_token={0}", accessToken);
    var timeline = await client.GetStringAsync(new Uri(apiUrl));

輔助方法:查詢字串解析

private string QueryString(string queryString, string key) {
    return Regex.Match(queryString, string.Format(@"(?<=(\&|^|\?)({0})\=).*?(?=\&|$)", key), RegexOptions.IgnoreCase).Value;
}

注意事項與原始碼下載

  • 需在 Live Connect 開發人員中心 註冊應用程式取得 App Key/Secret
  • 未通過審核的應用需在開放平台加入測試帳號,否則會遇到授權錯誤
  • Fiddler 可作為 HTTP 抓包分析工具

完整原始碼下載: https://files.cnblogs.com/webabcd/Windows8.rar

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved