欢迎来到《小5讲堂》,大家好,我是全栈小5。
这是2024年第3篇文章,此篇文章是C#知识点实践序列文章,博主能力有限,理解水平有限,若有不对之处望指正!
前言
上篇文章,我们已经了解到如果不进行地址编码,会存在数据丢失或者数据不正确的情况。
至于URL错误和安全问题,以及兼容性问题暂不做探索,这里只通过不编码解析情况探索。
数据丢失
这个比较好理解,就是传递过去的地址参数值不全,只有部分,另一部分数据丢失的情况。
下面将演示A地方发起http地址的get请求,传递未编码的地址参数,在目标接口接收到参数值的效果
效果
假设地址参数为:name=张三&小明&age=20&21
完整请求地址为:https://localhost:7250/WeatherForecast?name=张三&小明&age=20&21
地址参数中的&与符号是用来分隔不同参数变量,=等于符号后面是参数值。
从上图可以看到name参数的值应该是张三&小明,age参数的值应该是20&21,实际上获取到的值是name=张三,age=20。
原因就是地址参数的值就是从=等于号到下一个&符号结束,没有&符号就是=等于符号后面所有值。
因此,如果网址地址参数在通过http请求方式调用接口,不进行编码,就很有可能会丢失数据。
请求端代码
private async Task HttpGet()
{
string urlValue = $"https://localhost:7250/WeatherForecast?name=张三&小明&age=20&21";
using (HttpClient client = new HttpClient())
{
try
{
HttpResponseMessage response =await client.GetAsync(urlValue);
response.EnsureSuccessStatusCode(); // 确保请求成功,否则会抛出异常
string responseBody = await response.Content.ReadAsStringAsync();
Console.WriteLine(responseBody);
}
catch (HttpRequestException ex)
{
Console.WriteLine($"请求失败:{ex.Message}");
}
}
}
接口端代码
[HttpGet(Name = "GetWeatherForecast")]
public IEnumerable<WeatherForecast> Get(string name, int age)
{
string urlParam = Request.QueryString.Value;
return Enumerable.Range(1, 5).Select(index => new WeatherForecast
{
Date = DateTime.Now.AddDays(index),
TemperatureC = Random.Shared.Next(-20, 55),
Summary = Summaries[Random.Shared.Next(Summaries.Length)]
})
.ToArray();
}
数据编码
使用HttpUtility.UrlEncode进行数据编码
效果
从下图可以知道,.net core mvc框架本身会自动对编码数据进行解码
请求端代码
编码后数据,编码后发现无法调用到接口,那是因为接口age参数接收的是整型数据,因为框架有自己规则,所以需要改为字符串类型
https://localhost:7250/WeatherForecast?name=%e5%bc%a0%e4%b8%89%26%e5%b0%8f%e6%98%8e&age=20%2621
private async Task HttpGet()
{
string urlValue = $"https://localhost:7250/WeatherForecast?name={HttpUtility.UrlEncode("张三&小明")}&{HttpUtility.UrlEncode("age=20&21")}";
using (HttpClient client = new HttpClient())
{
try
{
HttpResponseMessage response =await client.GetAsync(urlValue);
response.EnsureSuccessStatusCode(); // 确保请求成功,否则会抛出异常
string responseBody = await response.Content.ReadAsStringAsync();
Console.WriteLine(responseBody);
}
catch (HttpRequestException ex)
{
Console.WriteLine($"请求失败:{ex.Message}");
}
}
}
接口端代码
[HttpGet(Name = "GetWeatherForecast")]
public IEnumerable<WeatherForecast> Get(string name, string age)
{
string urlParam = Request.QueryString.Value;
return Enumerable.Range(1, 5).Select(index => new WeatherForecast
{
Date = DateTime.Now.AddDays(index),
TemperatureC = Random.Shared.Next(-20, 55),
Summary = Summaries[Random.Shared.Next(Summaries.Length)]
})
.ToArray();
}
防止攻击
地址参数发起是在攻击者,他可以进行不编码传递,这个怎么防止攻击,可以采用以下措施。
1.进行输入检查和过滤
在服务端对传递的地址参数进行检查和过滤,以确保它们符合预期格式、类型、范围和规则。例如,可以检查参数是否是合法的URL或者做一定的输入数据格式的限制。
2.对地址参数进行编码
对地址参数进行URL编码或其他适合的编码,以确保传递的数据是安全的且不会被攻击者利用。
3.使用HTTPS协议进行数据传输
使用HTTPS协议加密数据传输,可以通过传输层或者网络层的加密来确保连接的安全性,可以有效防止数据的中途被中间人攻击窃取,提高防护能力。
4.避免在URL中传递敏感数据
避免在地址参数中传递敏感的数据,比较敏感的数据最好在进行传递时是采用POST方式进行,不要采用GET的方式。
总结:温故而知新,不同阶段重温知识点,会有不一样的认识和理解,博主将巩固一遍知识点,并以实践方式和大家分享,若能有所帮助和收获,这将是博主最大的创作动力和荣幸。也期待认识更多优秀新老博主。