首页 DotNet asp.net core web api自定义Swagger的UI界面及JWT身份认证的配置(二)

asp.net core web api自定义Swagger的UI界面及JWT身份认证的配置(二)

2024-09-13 08:59 编辑:  丽丽学习网

接上讲, asp.net core web api自定义Swagger的UI界面及JWT身份认证的配置(一)

八,新建控制器TokenController,获取token的控制器

/// <summary>
    /// 获取token
    /// </summary>
    [ApiController]
    [Route("[controller]/[action]")]
    public class TokenController : ControllerBase
    {
        private JwtTokenOption _jwtTokenOption;
        /// <summary>
        /// TokenController构造方法
        /// </summary>
        /// <param name="monitor"></param>
        public TokenController(IOptionsMonitor<JwtTokenOption> monitor)
        {
            _jwtTokenOption = monitor.CurrentValue;
        }
        /// <summary>
        /// 获取token
        /// </summary>
        /// <returns></returns>
        [HttpPost]
        public string GetToken()
        {
            // 有效载荷
            var claims = new[]
            {
                new Claim(ClaimTypes.Name,"丽丽学习网"),
                new Claim("NickName","hao366.net"),
                new Claim("Role","ptuser")//传递其他信息
};
            #region 非对称加密时用
            var rsa = RSA.Create();
            rsa.ImportRSAPrivateKey(Convert.FromBase64String(_jwtTokenOption.SecurityKey), out _);
            //需要加密:需要加密key:
            var credential = new SigningCredentials(new RsaSecurityKey(rsa),SecurityAlgorithms.RsaSha256);
            #endregion
            #region 对称加密时用下面的,先注释
            //对称加密时用下面的  HmacSha256 算法,加密key 长度至少是128位
            //var signingkey = new SymmetricSecurityKey(Convert.FromBase64String(_jwtTokenOption.SecurityKey));
            //var credential = new SigningCredentials(signingkey, SecurityAlgorithms.HmacSha256);
            #endregion
            // payload 中的信息声明
            var jwtSecurityToken = new JwtSecurityToken(
                issuer: _jwtTokenOption.Issuer,
                audience: _jwtTokenOption.Audience,
                claims: claims,
                expires: DateTime.Now.AddSeconds(_jwtTokenOption.TokenExpireTime),//过期时间,这里使用的是秒,那配置文件中的数字就是秒计算了
                signingCredentials: credential
            );
            var token = new
            JwtSecurityTokenHandler().WriteToken(jwtSecurityToken);
            return token;
        }
    }

此时可以运行程序了,浏览器输入的地址是 启动域名+ /index.html,先测试一下,看看swagger的界面是否改变了呢?

发现界面已经改变,有点像postman风格的。

同时 我们的token也拿到了。别急,还没有结束,只是拿到了token, 下面还有很多要做的事呢,一步一步的来。

九,新建一个需要受保护的HomeController, 一会儿我们用咱们刚才的验证和授权来保护这个Controller

/// <summary>
/// 受保护的资源
/// </summary>
[Authorize]
[ApiController]
[Route("[controller]/[action]")]
public class HomeController : ControllerBase
{
    /// <summary>
    /// 获取数据
    /// </summary>
    /// <returns></returns>
    [HttpGet]
    public MyResults GetData()
    {
        return MyResults.DataResult<string>("成功获取内容");
    }
}

十,第九步里用到了一个统一返回结果的固定格式,需要新建一个用于返回的类 MyResult.cs

/// <summary>
/// 统一数据响应格式
/// </summary>
public class MyResults
{
    /// <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 object? DataSource { get; set; }
    /// <summary>
    /// 返回的Token: 如果有值,则前端需要此这个值替旧的token值
    /// </summary>
    public string? Token { get; set; }
    /// <summary>
    /// 设置数据的结果
    /// </summary>
    /// <param name="data">数据</param>
    /// <returns></returns>
    public static MyResults DataResult<T>(T data)
    {
        return new MyResults() { Code = 1, DataSource = data, Msg = "请求成功", Success = true };
    }
    /// <summary>
    /// 响应成功的结果
    /// </summary>
    /// <param name="msg"></param>
    /// <returns></returns>
    public static MyResults SuccessResult(string msg = "请求成功")
    {
        return new MyResults() { Code = 1, DataSource = null, Msg = msg, Success = true };
    }
    /// <summary>
    /// 响应失败的结果
    /// </summary>
    /// <param name="msg"></param>
    /// <returns></returns>
    public static MyResults FailResult(string msg = "请求失败")
    {
        return new MyResults() { Code = -1, DataSource = null, 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 MyResults GetResult<T>(int code = 0, string? msg = null, T? data = default, bool success = true) where T : class, new()
    {
        return new MyResults() { Code = code, DataSource = data, Msg = msg, Success = success };
    }
    /// <summary>
    /// 设置token结果
    /// </summary>
    /// <param name="token"></param>
    /// <returns></returns>
    public static MyResults TokenResult(string token)
    {
        return new MyResults() { Code = 1, DataSource = null, Msg = "请求成功", Success = true, Token = token };
    }
}

此时看下,我们请求受保护的资源时,已经成功返回。

上面的请求注意, 带上从gettoen那里获取来的token, 如果不带,会提示 401 ,无法找到资源,说明这个资源是受保护的。这是最简单的资源授权验证的原理,当然,后面还会有用户登录等,用户登录后再获取token,  (即只有输入正确 的用户名和密码才可获取token),还有 token的刷新等,后面再说。