//只有登录的用户可以访问
1.统一返回格式
namespace webapi;
/// <summary>
/// 统一数据响应格式
/// </summary>
public class Results<T>
{
/// <summary>
/// 自定义的响应码,可以和http响应码一致,也可以不一致
/// </summary>
public int Code { get; set; }
/// <summary>
/// 中文消息提示
/// </summary>
public string? Msg { get; set; }
/// <summary>
/// 是否成功
/// </summary>
public bool Success { get; set; }
/// <summary>
/// 响应的数据
/// </summary>
public T? Data { get; set; }
/// <summary>
/// 返回的Token: 如果有值,则前端需要此这个值替旧的token值
/// </summary>
public string? Token { get; set; }
/// <summary>
/// 设置数据的结果
/// </summary>
/// <param name="data">数据</param>
/// <returns></returns>
public static Results<T> DataResult(T data)
{
return new Results<T> { Code = 1, Data = data, Msg = "请求成功", Success = true };
}
/// <summary>
/// 响应成功的结果
/// </summary>
/// <param name="msg"></param>
/// <returns></returns>
public static Results<T> SuccessResult(string msg = "操作成功")
{
return new Results<T> { Code = 1, Data = default, Msg = msg, Success = true };
}
/// <summary>
/// 响应失败的结果
/// </summary>
/// <param name="msg"></param>
/// <returns></returns>
public static Results<T> FailResult(string msg = "请求失败")
{
return new Results<T> { Code = -1, Data = default, Msg = msg, Success = false };
}
/// <summary>
/// 参数有误
/// </summary>
/// <param name="msg"></param>
/// <returns></returns>
public static Results<T> InValidParameter(string msg = "参数有误")
{
return new Results<T> { Code = -1, Data = default, Msg = msg, Success = false };
}
/// <summary>
/// 获取结果
/// </summary>
/// <param name="code"></param>
/// <param name="msg"></param>
/// <param name="data"></param>
/// <param name="success"></param>
/// <returns></returns>
public static Results<T> GetResult(int code = 0, string? msg = null, T? data = default, bool success = true)
{
return new Results<T> { Code = code, Data = data, Msg = msg, Success = success };
}
/// <summary>
/// 设置token结果
/// </summary>
/// <param name="token"></param>
/// <returns></returns>
public static Results<T> TokenResult(string token)
{
return new Results<T> { Code = 1, Data = default, Msg = "请求成功", Success = true, Token = token };
}
}
2.自定义授权过滤器
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
usinsg Microsoft.AspNetCore.Mvc.Authorization;
using Microsoft.AspNetCore.Mvc.Filters;
namespace webapi
{
/// <summary>
/// 授权过滤器
/// </summary>
[AttributeUsage(AttributeTargets.Class | AttributeTargets.Method, AllowMultiple = true, Inherited = true)]
public class CustomAuthorizeAttribute : Attribute, IAuthorizationFilter, IAuthorizeData
{
public CustomAuthorizeAttribute()
{
}
/// <summary>
/// 策略名称
/// </summary>
public string? Policy { get; set; }
/// <summary>
/// 可支持角色
/// </summary>
public string? Roles { get; set; }
/// <summary>
/// 以逗号分隔的方案列表,从中构造用户信息
/// </summary>
public string? AuthenticationSchemes { get; set; }
//public CustomAuthorizeAttribute(string policy) => this.Policy = policy;
/// <summary>
/// 授权时执行此方法
/// </summary>
public void OnAuthorization(AuthorizationFilterContext context)
{
// 需要排除具有AllowAnymons 这个标签的控制器
// 过滤掉带有AllowAnonymousFilter
if (HasAllowAnonymous(context))
{
return;
}
// 如果用户没有登录,则给出一个友好的提示(而不是返回401给前端)
if (!context.HttpContext.User.Identity.IsAuthenticated) // 判断是否登录
{
context.Result = new JsonResult(Results<string>.FailResult("Token无效"));
}
}
// 判断是否含有IAllowAnonymous
private bool HasAllowAnonymous(AuthorizationFilterContext context)
{
if (context.Filters.Any(filter => filter is IAllowAnonymousFilter))
{
return true;
}
// 终节点:里面包含了路由方法的所有元素信息(特性等信息)
var endpoint = context.HttpContext.GetEndpoint();
return endpoint?.Metadata.GetMetadata<IAllowAnonymous>() != null;
}
}
}
在需要授权的方法上使用TypeFilter特性表示要使用授权过滤器,也可以是用 [ServiceFilter(typeof(CustomAuthorizeAttribute))]
serviceFilter要输入服务
builder.Services.AddScoped<CustomAuthorizeAttribute>();
TypeFilter和serviceFilter都是局部注入,控制范围只能在某个控制器和方法,如果想要全局注入就要注入到控制器里
builder.Services.AddControllers(opt =>
{
opt.Filters.Add<CustomAuthorizeAttribute>();
});
不需要授权的接口可以使用
[AllowAnonymous]
[TypeFilter(typeof(CustomAuthorizeAttribute))]
[HttpGet(Name = "GetWeatherForecast")]
public IEnumerable<WeatherForecast> Get()
{
return Enumerable.Range(1, 5).Select(index => new WeatherForecast
{
Date = DateTime.Now.AddDays(index),
// Date = Convert.ToDateTime("2023-12-10 "),
TemperatureC = Random.Shared.Next(-20, 55),
Summary = Summaries[Random.Shared.Next(Summaries.Length)]
})
.ToArray();
}