如何解决如何保护ASP.NET Core Web API端点以仅允许来自React应用程序的请求?
我在一个Web应用程序中创建了一个ASP.NET Core Web API和React,并将其部署到生产环境中。
终点是:
www.myserver.com/obs是前端应用。
www.myserver.com/obs/api/GetValue是网络API。
如何保护Web API端点,以便只有来自React应用程序的请求才能调用API?
例如,如果我要在远程计算机上向www.myserver.com/obs/api/GetValue进行邮递员呼叫,则它不应返回资源。
一种方法是使用API密钥,但是您会将API密钥放在反应端的什么位置?我读到您可以将其放在.env文件中,但是在生产中,您仍然可以使用dev-tools找到该文件。
我读过的另一种选择是创建一个代理API,React应用程序会调用该代理,并且代理具有API密钥,但是这似乎有些过头了,我错过了一种更简单的方法吗?
解决方法
一种方法是使用API密钥,但是您会将API密钥放在哪里 在反应方面?
是的,您可以创建一个API密钥中间件并将其用于验证请求。如果请求来自React应用程序,则可以在请求标头中添加API密钥。像这样的代码:
使用提取方法:
fetch('/api/MoviesAPI',{
method: 'Get',// or 'Post'
headers: {
'Content-Type': 'application/json','ApiKey':'Test-value',},})
.then(response => response.json())
.then(data => {
console.log('Success:',data);
})
.catch((error) => {
console.log('Error:',error);
});
使用Ajax方法:
$.ajax({
type: "Get",url: "/api/MoviesAPI",//remember change the controller to your owns.
contentType: 'application/json',beforeSend: function (xhr) { xhr.setRequestHeader('ApiKey','test-value'); },success: function (data) {
console.log(data)
},failure: function (response) {
console.log(response.responseText);
},error: function (response) {
console.log(response.responseText);
}
});
有关在reactjs中发送带有自定义标头的请求的更多详细信息,您可以使用Google或Bing搜索“带有自定义标头的reactjs调用api”,其中有很多相关文章。
此外,关于创建API密钥中间件,您可以参考以下步骤:
-
在API应用程序中创建ApiKeyMiddleware.cs类,并添加以下代码:
public class ApiKeyMiddleware { public ApiKeyMiddleware(RequestDelegate next,IConfiguration configuration) { _next = next; _configuration = configuration; } private readonly RequestDelegate _next; private readonly IConfiguration _configuration; public async Task Invoke(HttpContext context) { if (context.Request.Path.StartsWithSegments(new PathString("/api"))) { //Let's check if this is an API Call if (context.Request.Headers.Keys.Contains("ApiKey",StringComparer.InvariantCultureIgnoreCase)) { // validate the supplied API key // Validate it var headerKey = context.Request.Headers["ApiKey"].FirstOrDefault(); await ValidateApiKey(context,_next,headerKey); } else { await _next.Invoke(context); } } else { await _next.Invoke(context); } } private async Task ValidateApiKey(HttpContext context,RequestDelegate next,string key) { // validate it here var valid = false; var Apikey = _configuration["ApiKey"]; if (key != null && key==Apikey) { valid = true; } if (!valid) { context.Response.StatusCode = (int)HttpStatusCode.Unauthorized; await context.Response.WriteAsync("Invalid API Key"); } else { var identity = new GenericIdentity("API"); var principal = new GenericPrincipal(identity,new[] { "Admin","ApiUser" }); context.User = principal; await next.Invoke(context); } } }
-
在Startup.cs文件的Configure方法中注册此中间件。
app.UseMiddleware<ApiKeyMiddleware>(); //add APIkeyMiddleware app.UseHttpsRedirection(); app.UseStaticFiles(); app.UseRouting(); app.UseAuthentication(); //Call the UseAuthentication app.UseAuthorization();
-
在API控制器或操作方法中,添加
Authorize
属性。[HttpGet] [Authorize] public async Task<ActionResult> GetMovie() { return Ok(await _context.Movie.ToListAsync()); }
然后,如果请求标头中不包含ApiKey或键值无效,则它将不返回资源。
编辑:
关于API密钥值,您可以将它们存储在appsettings.json文件或“内存.NET”对象中。使用它时,您可以从“配置”中获取它。
例如:将其存储在appsettings.json文件中:
{
...
"Apikey": "my Test API key"
}
然后,使用以下代码获取键值
public ApiKeyMiddleware(RequestDelegate next,IConfiguration configuration)
{
_next = next;
_configuration = configuration;
}
private readonly RequestDelegate _next;
private readonly IConfiguration _configuration;
private async Task ValidateApiKey(HttpContext context,string key)
{
// validate it here
var valid = false;
//get the key value from configuration.
var Apikey = _configuration["ApiKey"];
...
在React端,您可以创建一个服务来获取此键值,然后使用api键发送请求。
,不能。您的react应用可被浏览器读取,因此,任何知道如何使用浏览器开发人员工具或在其计算机上拦截HTTP请求的人都可以读取。 如果您的react应用程序可以与您的API通讯,那么其他人也可以。代理也是如此。您可以找到更详细的答案here。
如果您想控制访问权限,则可以引入身份验证,并且仅将访问权限授予受信任的用户,但是如果他们确实愿意,您仍然不能阻止他们访问您的react应用之外的API。
您可以采取一些措施来增加难度。我建议您阅读有关创建安全API的内容。一些使您入门的链接:
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。