我们在做 Api 接口时,相信一定会有接触到要给传输的请求 body 的内容进行加密传输。其目的就是为了防止一些敏感的内容直接被 UI 层查看或篡改。
其实粗略一想就能想到很多种方案,但是哪些方案是目前最适合我们项目的呢?
硬编码方式
最先想到的应该就是硬编码方式,就是哪个接口需要进行传输加密,那么就针对该接口特殊处理:
public class SecurityApiController {
...
public async Task UpdateUser([FromBody] SecurityRequest request) {
var requestBody = RsaHelper.Decrypt(privateKey, request.Content);
var user = JsonHelper.Deserialize(requestBody);
await UpdateUserAsync(user);
return new Result(RsaHelper.Encrypt(publicKey, new{ Success=true}));
}
}
// 文件 UserController.cs
public partial class BaseController {
...
}
// 文件 AccountController.cs
public partial class BaseController {
}
// ...
这样势必就会导致一个明显的问题,就是“代码爆炸”。这相当于将所有的业务逻辑全部灌输到一个控制器中,刚开始写的时候方便了,但是后期维护以及交接换人的时候阅读代码是非常痛苦的一个过程。因为在不同的 Controller 文件中势必会重复初始化一些模块,而我们在引用方法的时候 IDE 每次都会显示上千个方法,有时候还不得不查看哪些方法名一样或相近的具体意义。
public class SecurityTransportModelBinder : IModelBinder {
...
public async Task BindModelAsync(ModelBindingContext bindingContext)
{
if (bindingContext == null)
{
throw new ArgumentNullException(nameof(bindingContext));
}
try
{
var request = bindingContext.HttpContext.Request;
var model = await JsonSerializer.DeserializeAsync<SafeDataWrapper>(request.Body, new JsonSerializerOptions
{
PropertyNamingPolicy = JsonNamingPolicy.CamelCase,
});
var decryptContent = RsaHelper.Decrypt(model.Info, privateKey);
var activateModel = JsonSerializer.Deserialize(decryptContent, bindingContext.ModelMetadata.ModelType, new JsonSerializerOptions
{
PropertyNamingPolicy = JsonNamingPolicy.CamelCase,
});
//重新包装
if (activateModel == null)
{
bindingContext.Result = ModelBindingResult.Failed();
}
else
{
bindingContext.Result = ModelBindingResult.Success(activateModel);
}
}
catch (Exception exception)
{
bindingContext.ModelState.TryAddModelError(
bindingContext.ModelName,
exception,
bindingContext.ModelMetadata);
}
_logger.DoneAttemptingToBindModel(bindingContext);
//return Task.CompletedTask;
}
}
抄了 ModelBinder 还不行,还要抄 ModelBinderProvider:
public class SecurityTransportModelBinderProvider : IModelBinderProvider
{
public IModelBinder GetBinder(ModelBinderProviderContext context)
{
if (context == null)
{
throw new ArgumentNullException(nameof(context));
}
if (context.Metadata.IsComplexType && typeof(IApiEncrypt).IsAssignableFrom(context.Metadata.ModelType))
{
var loggerFactory = context.Services.GetRequiredService();
var configuration = context.Services.GetRequiredService();
return new SecurityTransportModelBinder(loggerFactory, configuration);
}
return null;
}
}
public class UserUpdateRequest: IApiEncrypt {
public int UserId { get; set; }
public string Phone { get; set; }
public string Address { get; set; }
...
}
转自于:http://www.iteye.com/problems/23775
问:
我在开发过程中,使用hql进行查询(mysql5)使用到了mysql自带的函数find_in_set()这个函数作为匹配字符串的来讲效率非常好,但是我直接把它写在hql语句里面(from ForumMemberInfo fm,ForumArea fa where find_in_set(fm.userId,f
1、下载软件 rzsz-3.34.tar.gz。登录linux,用命令
wget http://freeware.sgi.com/source/rzsz/rzsz-3.48.tar.gz下载。
2、解压 tar zxvf rzsz-3.34.tar.gz
3、安装 cd rzsz-3.34 ; make posix 。注意:这个软件安装与常规的GNU软件不
Forwarded port
Private network
Public network
Vagrant 中一共有三种网络配置,下面我们将会详解三种网络配置各自优缺点。
端口映射(Forwarded port),顾名思义是指把宿主计算机的端口映射到虚拟机的某一个端口上,访问宿主计算机端口时,请求实际是被转发到虚拟机上指定端口的。Vagrantfile中设定语法为:
c
Given a 2D board and a word, find if the word exists in the grid.
The word can be constructed from letters of sequentially adjacent cell, where "adjacent" cells are those horizontally or ve