C#客户端HttpClient请求认证及数据传输

目录
  • 一,授权认证
    • 1. 基础认证示例
    • 2. JWT 认证示例
    • 3. Cookie 示例
  • 二,请求类型
  • 三,数据传输
    • 1. Query
    • 2. Header
    • 3. 表单
    • 4. JSON
    • 5. 上传文件

一,授权认证

客户端请求服务器时,需要通过授权认证许可,方能获取服务器资源,目前比较常见的认证方式有 Basic 、JWT、Cookie。

HttpClient 是 C# 中的 HTTP/HTTPS 客户端,用于发送 HTTP 请求和接收来自通过 URI 确认的资源的 HTTP 响应。下面以具体代码做示范。

1. 基础认证示例

        // Basic基础认证
        public async Task Basic(string user, string password, string url)
        {
            // 如果认证页面是 https 的,请参考一下 jwt 认证的 HttpClientHandler
            // 创建  client
            HttpClient client = new HttpClient();

            // 创建身份认证
            // using System.Net.Http.Headers;
            AuthenticationHeaderValue authentication = new AuthenticationHeaderValue(
                "Basic",
                Convert.ToBase64String(Encoding.UTF8.GetBytes($"{user}:{password}")
                ));

            client.DefaultRequestHeaders.Authorization = authentication;

            byte[] response = await client.GetByteArrayAsync(url);
            client.Dispose();
        }

可以看到 Basic 认证的安全程度非常低,多用于路由器和嵌入式设备,而且往往不会使用 HTTPS。

2. JWT 认证示例

        // Jwt认证
        public async Task Bearer(string token, string url)
        {
            // HttpClientHandler及其派生类使开发人员能够配置各种选项, 包括从代理到身份验证。
            // helpLink https://docs.microsoft.com/en-us/dotnet/api/system.net.http.httpclienthandler?view=netframework-4.8
            var httpclientHandler = new HttpClientHandler();

            // 如果服务器有 https 证书,但是证书不安全,则需要使用下面语句
            // => 也就是说,不校验证书,直接允许
            httpclientHandler.ServerCertificateCustomValidationCallback = (message, cert, chain, error) => true;

            using (var httpClient = new HttpClient(httpclientHandler))
            {
                // 创建身份认证
                // System.Net.Http.Headers.AuthenticationHeaderValue;
                httpClient.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", token);
                await httpClient.GetAsync(url);
                httpClient.Dispose();
            }
        }

JWT 认证,需要客户端携带 token ,token 是一段加密过的字符串,关于原理这里不多说,token 是通过客户端 header 携带的。

另外,对于测试的 Web 应用或者内网应用, HTTPS 证书可能不是公网国际认证的证书,就需要跳过认证,直接允许访问使用。

            var httpclientHandler = new HttpClientHandler()
            {
                ServerCertificateCustomValidationCallback = (message, cert, chain, error) => true,
            };

3. Cookie 示例

HttpClient 中,Cookie 有两种处理方式。

一种是已经知道 Cookie ,直接将 Cookie 存储到 HttpClient 中;另一种是还没有 Cookie ,通过账号密码登录获取到 Cookie ,自动存储到 HttpClient 对象中,接着使用当前 HttpClient 对象请求 URL。

两种方式的设定,是通过 HttpClientHandler 的 UseCookies 属性设置的。

示例

            var httpclientHandler = new HttpClientHandler()
            {
                UseCookies = true
            };

​ UseCookies 获取或设置一个值,该值指示处理程序是否使用 CookieContainer 属性存储服务器 Cookie,并在发送请求时使用这些 Cookie。

方式1:

        // 先用账号密码登陆再请求
        public async Task Cookie(string user, string password, string loginUrl, string url)
        {
            var httpclientHandler = new HttpClientHandler()
            {
                ServerCertificateCustomValidationCallback = (message, cert, chain, error) => true,
                UseCookies = true
            };
            // 如果服务器有 https 证书,但是证书不安全,则需要使用下面语句
            // => 也就是说,不校验证书,直接允许

            var loginContent = new FormUrlEncodedContent(new[]
            {
             new KeyValuePair<string,string>("user",user),
             new KeyValuePair<string, string>("password",password)
            });
            using (var httpClient = new HttpClient(httpclientHandler))
            {
                // 先登陆
                var result = await httpClient.PostAsync(loginUrl, loginContent);
                // 登陆成功后,客户端会自动携带 cookie ,不需要再手动添加
                //if (result.IsSuccessStatusCode)
                //{
                //    /*
                //     * 如果请求成功
                //     */
                //}

                var result2 = await httpClient.GetAsync(url);
                // httpclient 已经携带 Cookie ,可以多次使用
                // var result3 = await httpClient.GetAsync(url3);
                // var result4 = await httpClient.GetAsync(url4);
                httpClient.Dispose();
            }
        }

方式2:

        //已经拿到 cookie ,直接使用 cookie 请求
        public async Task Cookie(string cookie, string url)
        {
            var httpclientHandler = new HttpClientHandler()
            {
                ServerCertificateCustomValidationCallback = (message, cert, chain, error) => true,
                UseCookies = false
            };
            // 如果服务器有 https 证书,但是证书不安全,则需要使用下面语句
            // => 也就是说,不校验证书,直接允许

            using (var httpClient = new HttpClient(httpclientHandler))
            {
                httpClient.DefaultRequestHeaders.Add("Cookie", cookie);
                await httpClient.GetAsync(url);
                httpClient.Dispose();
            }
        }

二,请求类型

HTTP 请求里,有 GET、POST、DELETE、PUT 等请求方式。

HttpClient 中,有以下请求相关的方法

  • CancelPendingRequests
  • DeleteAsync
  • GetAsync
  • GetByteArrayAsync
  • GetStreamAsync
  • GetStringAsync
  • PostAsync
  • PutAsync
  • SendAsync

其中, CancelPendingRequests 是取消该实例所有挂起的请求,不是请求类型。

SendAsync 用于处理送 HttpRequestMessage(表示一条 HTTP 请求消息),比较原生。

对于 GetAsync、PostAsync等请求方法,使用过程类似,下面是使用示例

        public async void Request(string url)
        {

            using (var httpClient = new HttpClient())
            {
                // HttpClient 中,所有 Get 请求都是异步的
                HttpResponseMessage result = await httpClient.GetAsync(url);

                // Task<>.Result 可以获取异步结果
                result = httpClient.GetAsync(url).Result;

                //var result1 = await httpClient.GetByteArrayAsync(url);
                //var result1 = await httpClient.GetStreamAsync(url);
                //var result1 = await httpClient.GetStringAsync(url);

                // ByteArrayContent

                FormUrlEncodedContent fromContent = new FormUrlEncodedContent(new[]
                {
                    new KeyValuePair<string,string>("Email","123@qq.com"),
                    new KeyValuePair<string, string>("Number","666")
                });
                // 使用 Post ,必须携带 继承 HttpContent 的对象
                // 就是说,Post 必须要上传数据
                result = await httpClient.PostAsync(url, fromContent);

                // 如果没有数据要上传,可以使用 null
                result = await httpClient.PostAsync(url, null);

                httpClient.Dispose();
            }

三,数据传输

HTTP/HTTPS 请求中,往往随着数据传输,例如表单提交、JSON上传、文件上传等,下面以代码示范。

1. Query

ASP.NET Core API 可以这样写

        [HttpPost("aaa")]
        public async Task<JsonResult> AAA(int? a, int? b)
        {
            if (a == null || b == null)
                return new JsonResult(new { code = 0, result = "aaaaaaaa" });
            return new JsonResult(new { code = 2000, result = a + "|" + b });
        }

HttpClient

        // URL Query 参数
        public void Query(string a, string b)
        {
            var httpclientHandler = new HttpClientHandler()
            {
                ServerCertificateCustomValidationCallback = (message, cert, chain, error) => true,
            };
            using (var httpClient = new HttpClient(httpclientHandler))
            {

                var result = httpClient.PostAsync($"https://localhost:5001/test?a={a}&b={b}", null).Result;

                httpClient.Dispose();
            }
        }

2. Header

Header 是以键值形式存储的,HttpClient 示例

        // Header 头
        public void Header()
        {
            var httpclientHandler = new HttpClientHandler()
            {
                ServerCertificateCustomValidationCallback = (message, cert, chain, error) => true,
            };
            using (var httpClient = new HttpClient(httpclientHandler))
            {
                httpClient.DefaultRequestHeaders.Add("MyEmail", "123@qq.com");
                var result = httpClient.GetAsync($"https://localhost:5001/test").Result;

                httpClient.Dispose();
            }
        }

ASP.NET Core API 示例

        [HttpPost("ddd")]
        public async Task<JsonResult> DDD([FromHeader]int? a, [FromHeader]int? b)
        {
            if (a == null || b == null)
                return new JsonResult(new { code = 0, result = "aaaaaaaa" });
            return new JsonResult(new { code = 200, result = a + "|" + b });
        }

3. 表单

        //  表单提交
        // application/x-www-form-urlencoded
        public void From()
        {
            var httpclientHandler = new HttpClientHandler()
            {
                ServerCertificateCustomValidationCallback = (message, cert, chain, error) => true,
            };

            var fromContent = new FormUrlEncodedContent(new[]
            {
             new KeyValuePair<string,string>("Id","1"),
             new KeyValuePair<string,string>("Name","痴者工良"),
             new KeyValuePair<string, string>("Number","666666")
            });

            using (var httpClient = new HttpClient(httpclientHandler))
            {
                var result = httpClient.PostAsync("https://localhost:5001/test", fromContent).Result;

                Console.WriteLine(result.Content.ReadAsStringAsync().Result);
                httpClient.Dispose();
            }
        }

4. JSON

除了 JSON ,还有

  • text/html
  • application/javascript
  • text/plain
  • application/xml

他们都是使用 StringContent 来表示。

        // Json 等
        public void StringAnd(string json)
        {
            var httpclientHandler = new HttpClientHandler()
            {
                ServerCertificateCustomValidationCallback = (message, cert, chain, error) => true,
            };

            var jsonContent = new StringContent(json);

            // Json 是 StringContent,上传时要指定 Content-Type 属性,除此外还有
            // text/html
            // application/javascript
            // text/plain
            // application/xml
            jsonContent.Headers.ContentType = new System.Net.Http.Headers.MediaTypeHeaderValue("application/json");

            using (var httpClient = new HttpClient(httpclientHandler))
            {

                var result = httpClient.PostAsync("https://localhost:5001/test", jsonContent).Result;

                Console.WriteLine(result.Content.ReadAsStringAsync().Result);
                httpClient.Dispose();
            }
        }

5. 上传文件

API 这样写

      [HttpPost]    //上传文件是 post 方式,这里加不加都可以
        public async Task<IActionResult> UploadFiles(List<IFormFile> files)
        {
        // ...
        }

HttpClient 写法

        // 上传文件
        public async Task File(string filepath, string fromName, string url)
        {
            using (var client = new HttpClient())
            {
                FileStream imagestream = System.IO.File.OpenRead(filepath);
                // multipartFormDataContent.Add();
                var multipartFormDataContent = new MultipartFormDataContent()
                {
                    {
                        new ByteArrayContent(System.IO.File.ReadAllBytes(filepath)),    // 文件流
                        fromName,                                                       // 对应 服务器 WebAPI 的传入参数
                        Path.GetFileName(filepath)                                      // 上传的文件名称
                    }
                };
                /*
                 * 如果服务器 API 写法是
                 * ([FromForm]IFromFile files)
                 * 那么上面的 fromName="files"
                 */
                // multipartFormDataContent.Headers.ContentType = MediaTypeHeaderValue.Parse("multipart/form-data");

                HttpResponseMessage response = await client.PostAsync(url, multipartFormDataContent);
                if (!response.IsSuccessStatusCode)
                {

                    Console.WriteLine("up image error");
                    Console.WriteLine(response.RequestMessage);
                }
            }
        }

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持我们。

(0)

相关推荐

  • C# 使用Fiddler捕获本地HttpClient发出的请求操作

    示例接口定义 为了方便笔者先自己写了个简单的接口用于展示,返回当前时间,具体如下 /// <summary> /// GetToday. /// </summary> /// <returns></returns> [HttpGet] [Route("GetTime/Today")] public MyDateTime GetToday() { var now = DateTime.Now; return new MyDateTime {

  • C#使用HttpClient的正确方式你了解吗

    目录 错误使用 New HttpClient static HttpClient 正确使用 错误使用 New HttpClient 如下面一段代码,日常开发中经常使用的 call http 方式,每次 new 一个 HttpClient using(var client = new HttpClient()) 先来做一个简单的测试,循环 call 一个 url ,代码如下 public async Task<string> GetXXXUrlAsync(string url) { var ht

  • C# 使用HttpClient模拟请求的案例

    情景描述 将一个时间转换为对应的unix时间戳, 字符集使用UTF-8编码,数据通讯统一采用 HTTP 协议通讯,使用POST 方法请求并传递参数. POST请求Content-Type 设置为application/x-www-form-urlencoded 除此之外,我们对请求添加签名的校验,key设置为X-Sign 接口定义 /// <summary> /// 获取时间戳(毫秒). /// </summary> /// <param name="dateTim

  • c# HttpClient设置超时的步骤

    HttpClient作为官方推荐的http客户端,相比之前的WebClient和WebRequest好用了很多,但默认无法为每个请求单独设置超时,只能给HttpClient设置默认超时,使用起来不太方便. 声明:本文主要是翻译自THOMAS LEVESQUE'S .NET BLOG的文章:Better timeout handling with HttpClient. 由于工作原因,需要用c#,就语法层而言,c#确实比java优秀,一些库接口封装也更方便简洁.特别是HttpClient,结合了t

  • C# HttpClient Cookie验证解决方法

    自实现的cookie 验证,远程取值的例子 以下代码配合HttpClient使用可以实现跨域(cookie的读写) //验证 复制代码 代码如下: HttpClient httpClient = new HttpClient(url, null, true); httpClient.PostingData.Add(key,value);//登录用户名 httpClient.PostingData.Add(key,value);//密码 string str = httpClient.GetStr

  • C# HttpClient 如何使用 Consul 发现服务

    试用了Overt.Core.Grpc, 把 GRPC 的使用改造得像 WCF, 性能测试也非常不错, 非常推荐各位使用. 但已有项目大多是 http 请求, 改造成 GRPC 的话, 工作量比较大, 于是又找到了 Steeltoe.Discovery, 在 Startup 给 HttpClient 添加 DelegatingHandler, 动态改变请求url中的 host 和 port, 将http请求指向consul 发现的服务实例, 这样就实现了服务的动态发现. 经过性能测试, Steel

  • C#中HttpWebRequest、WebClient、HttpClient的使用详解

    HttpWebRequest: 命名空间: System.Net,这是.NET创建者最初开发用于使用HTTP请求的标准类.使用HttpWebRequest可以让开发者控制请求/响应流程的各个方面,如 timeouts, cookies, headers, protocols.另一个好处是HttpWebRequest类不会阻塞UI线程.例如,当您从响应很慢的API服务器下载大文件时,您的应用程序的UI不会停止响应.HttpWebRequest通常和WebResponse一起使用,一个发送请求,一个

  • C# 使用HttpClient上传文件并附带其他参数的步骤

    HttpClient和MultipartFormDataContent(传送门)最低适用于.NET Framework 4.5版本 发送端代码 using (HttpClient client = new HttpClient()) { var content = new MultipartFormDataContent(); //添加字符串参数,参数名为qq content.Add(new StringContent("123456"), "qq"); strin

  • C#客户端HttpClient请求认证及数据传输

    目录 一,授权认证 1. 基础认证示例 2. JWT 认证示例 3. Cookie 示例 二,请求类型 三,数据传输 1. Query 2. Header 3. 表单 4. JSON 5. 上传文件 一,授权认证 客户端请求服务器时,需要通过授权认证许可,方能获取服务器资源,目前比较常见的认证方式有 Basic .JWT.Cookie. HttpClient 是 C# 中的 HTTP/HTTPS 客户端,用于发送 HTTP 请求和接收来自通过 URI 确认的资源的 HTTP 响应.下面以具体代码

  • java发送HttpClient请求及接收请求结果过程的简单实例

    一. 1.写一个HttpRequestUtils工具类,包括post请求和get请求 package com.brainlong.framework.util.httpclient; import net.sf.json.JSONObject; import org.apache.commons.httpclient.HttpStatus; import org.apache.http.HttpResponse; import org.apache.http.client.methods.Htt

  • httpclient 请求http数据,json转map的实例

    实例如下: package com.idc.dataAudit.dataResource; import java.util.ArrayList; import java.util.HashMap; import java.util.Iterator; import java.util.List; import java.util.Map; import net.sf.json.JSONArray; import net.sf.json.JSONObject; import org.apache

  • node.js中express模块创建服务器和http模块客户端发请求

    首先下载express模块,命令行输入 npm install express 1.node.js中express模块创建服务端 在js代码同文件位置新建一个文件夹(www_root),里面存放网页文件等,就可以在浏览器中访问了 var express = require("express"); var path = require("path"); var app = express(); //目录 (当前目录下的www_root目录) app.use(expre

  • Java后台防止客户端重复请求、提交表单实现原理

    这篇文章主要介绍了Java后台防止客户端重复请求.提交表单实现原理,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下 前言 在Web / App项目中,有一些请求或操作会对数据产生影响(比如新增.删除.修改),针对这类请求一般都需要做一些保护,以防止用户有意或无意的重复发起这样的请求导致的数据错乱. 常见处理方案 1.客户端 例如表单提交后将提交按钮设为disable 等等方法... 2.服务端 前端的限制仅能解决少部分问题,且不够彻底,后端自有的

  • HttpClient 请求 URL字符集转码问题

    问题是这样的,我用eclipse发送httpclient请求如下没有问题,但是在idea中就返回400,为毛呢???excuse me? package com.vol.timingTasks; import org.apache.http.HttpEntity; import org.apache.http.HttpResponse; import org.apache.http.auth.AuthScope; import org.apache.http.auth.UsernamePassw

  • Android客户端post请求服务器端实例

    Android客户端请求服务器端的详细解释 1. Android客户端与服务器端通信方式: Android与服务器通信通常采用HTTP通信方式和Socket通信方式,而HTTP通信方式又分get和post两种方式. 2. 解析服务器端返回数据的解释: (1).对于服务器端来说,返回给客户端的数据格式一般分为html.xml和json这三种格式. (2). JSON(Javascript Object Notation)是一种轻量级的数据交换格式,相比于xml这种数据交换格式来说,因为解析xml比

  • Python confluent kafka客户端配置kerberos认证流程详解

    kafka的认证方式一般有如下3种: 1.SASL/GSSAPI 从版本0.9.0.0开始支持 2.SASL/PLAIN 从版本0.10.0.0开始支持 3.SASL/SCRAM-SHA-256 以及 SASL/SCRAM-SHA-512 从版本0.10.2.0开始支持 其中第一种SASL/GSSAPI的认证就是kerberos认证,对于java来说有原生的支持,但是对于python来说配置稍微麻烦一些,下面说一下具体的配置过程,confluent kafka模块底层依赖于librdkafka,

  • 解决Node.js mysql客户端不支持认证协议引发的问题

    前言 mysql模块(项目地址为https://github.com/mysqljs/mysql)是一个开源的.JavaScript编写的MySQL驱动,可以在Node.js应用中来操作MySQL.但在使用过程中,出现了"ER_NOT_SUPPORTED_AUTH_MODE"问题. 本文介绍了出现该问题的原因及解决方案. 报错信息 当我试图使用mysql模块来连接MySQL 8时,出现了如下错误信息: D:\workspaceGithub\nodejs-book-samples\sam

  • 浅谈PostgreSQL的客户端认证pg_hba.conf

    大家都知道防火墙主要是用来过滤客户端并保护服务器不被恶意访问攻击,那在pg中同样存在一个类似于防火墙的工具用来控制客户端的访问,也就是pg_hba.conf这个东东. 在initdb初始化数据文件时,默认提供pg_hba.conf. 通过配置该文件,能够指定哪些ip可以访问,哪些ip不可以访问,以及访问的资源和认证方式,该文件类似于oracle中的监听中的白名单黑名单功能,且同样可以reload在线生效. 记录可以是下面七种格式之一: local database user auth-metho

随机推荐