C#客户端HttpClient请求认证及数据传输
作者:痴者工良 发布时间:2023-06-11 21:11:00
一,授权认证
客户端请求服务器时,需要通过授权认证许可,方能获取服务器资源,目前比较常见的认证方式有 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);
}
}
}
来源:https://www.cnblogs.com/whuanle/p/11656734.html
猜你喜欢
- spring中事务处理原理 利用aop生成代理对象执行带有Transactional事务注解的
- 一、环境准备准备开发环境创建一个Maven项目pom.xml添加依赖resources下添加spring的配置文件applicationCo
- 命令模式定义:将请求封装成对象,这可以让你使用不同的请求、队列、或者日志来参数化其他对象。何时使用命令模式?当需要将发出请求的对象和执行请求
- Maven是项目对象模型(POM),可以通过一小段描述信息来管理项目的构建,报告和文档的项目管理工具软件。Maven是一个项目管理工具,它包
- 通常来说,多线程的并发及条件断点的debug是很难完成的,或许本篇文章会给你提供一个友好的调试方法。让你在多线程开发过程中的调试更加的有的放
- 下载和上传附件、发送短信和发送邮件,都算是程序中很常用的功能,之前记录了文件的上传和下载还有发送短信,由于最近比较忙,邮件发送的功能就没有时
- 小程序官方流程图如下,官方地址 : https://developers.weixin.qq.com/miniprogram/dev/fra
- 这篇文章主要讲解C#中的泛型,泛型在C#中有很重要的地位,尤其是在搭建项目框架的时候。一、什么是泛型泛型是C#2.0推出的新语法,不是语法糖
- 前言早就听说Go语言开发的服务不用任何架构优化,就可以轻松实现百万级别的qps。这得益于Go语言级别的协程的处理效率。协程不同于线程,线程是
- 之前学习 Java 的时候,感觉最难做的一件事情就是配置 jdk 的环境。那叫一个困难啊,Path, JAVA_HOME, CLASSPAT
- 介绍 在开发过程中,我们有时候会遇到非接口调用而出发程序执行任务的一些场景,比如我们使用quartz定时框架通过配置文件来启动定时任务时,
- JDK中的三个基本注解a、@Override:检查子类确实是覆盖了父类的方法。b、@Deprecated:说明已经过时了。c、@Suppre
- 在Spring MVC中想要对每一个URL进行权限控制,不想手工整理这样会有遗漏,所以就动手写程序了。代码如下: /** &nb
- 本文实例为大家分享了C#实现文件上传与下载的具体代码,供大家参考,具体内容如下C#实现文件上传代码: public ActionResult
- 本文实例为大家分享了Android自定义View画圆的具体代码,供大家参考,具体内容如下引入布局<?xml version="
- 本文实例讲述了C#简单实现显示中文格式星期几的方法。分享给大家供大家参考,具体如下:1.DateTime.Now.ToString(&quo
- 使用字典存储事件实例accessor-declarations 的一种用法是公开很多事件但不为每个事件分配字段,而是使用字典来存储这些事件实
- C#串口模块的使用。使用VS .net框架下WinForm程序应用开发。C#开发的串口通信小工具。相比于QT添加的串口类,WinForm是通
- async和awaitasync微软文档:使用 async 修饰符可将方法、lambda 表达式或匿名方法指定为异步。使
- Bean是Spring框架中最核心的两个概念之一(另一个是面向切面编程AOP)。1 定义Spring 官方文档对 bean 的解释是:In