.NetCore 3.1 JWT AccessToken And RefreshToken

Controller

    [HttpGet]
    public Response<JwtDto> Login(string account, string password)
    {
        var response = new Response<JwtDto>();

        var user = students.SingleOrDefault(t => t.Account == account);

        if (user != null)
        {
            if (user.Password.Equals(password))
            {
                response.Msg = "登录成功";

                var token = new JwtDto()
                {
                    AccessToken = Jwt.CreateToken(user, TokenType.AccessToken),
                    RefreshToken = Jwt.CreateToken(user, TokenType.RefreshToken)
                };

                response.Data = token;
            }
            else
            {
                response.Status = 400;
                response.Msg = "用户密码不正确!";
            }
        }
        else
        {
            response.Status = 400;
            response.Msg = "用户名不存在!";
        }

        return response;
    }

    [HttpGet]
    public Response<string> RefreshToken(string refreshToken)
    {
        Student student;
        var response = new Response<string>();

        if (Jwt.ValidateRefreshToken(refreshToken.ToStringX().Replace("Bearer ", ""), out student))
        {
            response.Data = Jwt.CreateToken(student, TokenType.AccessToken);
        }
        else
        {
            response.Status = 401;
            response.Msg = "Unauthorized";
        }

        return response;
    }

JWT

   public class Jwt
    {
        public static string CreateToken(Student student, TokenType type)
        {
            var audience = type == TokenType.AccessToken ? AppSettings.JWT.AccessTokenAudience : AppSettings.JWT.RefreshTokenAudience;

            var expires = type == TokenType.AccessToken ? AppSettings.JWT.AccessTokenExpires : AppSettings.JWT.RefreshTokenExpires;

            var claims = new Claim[] {
                    new Claim(ClaimTypes.Name, student.Account),
                    new Claim(JwtRegisteredClaimNames.Iss,AppSettings.JWT.Issuer),
                    new Claim(JwtRegisteredClaimNames.Aud,audience),
                    new Claim(JwtRegisteredClaimNames.Nbf,$"{new DateTimeOffset(DateTime.Now).ToUnixTimeSeconds()}"),
                    new Claim(JwtRegisteredClaimNames.Exp,$"{new DateTimeOffset(DateTime.Now.AddSeconds(expires)).ToUnixTimeSeconds()}")
                };

            var key = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(AppSettings.JWT.SecurityKey));
            var signingCredentials = new SigningCredentials(key, SecurityAlgorithms.HmacSha256);

            var securityToken = new JwtSecurityToken(
                    issuer: AppSettings.JWT.Issuer,
                    audience: audience,
                    claims: claims,
                    expires: DateTime.Now.AddSeconds(expires),
                    signingCredentials: signingCredentials);

            return "Bearer " + new JwtSecurityTokenHandler().WriteToken(securityToken);
        }

        public static bool ValidateRefreshToken(string refreshToken, out Student student)
        {
            var tokenValidationParameters = new TokenValidationParameters
            {
                ValidateIssuer = true,
                ValidIssuer = AppSettings.JWT.Issuer,
                ValidateAudience = true,
                ValidAudience = AppSettings.JWT.RefreshTokenAudience,
                ValidateLifetime = true,
                ClockSkew = TimeSpan.FromSeconds(0),
                ValidateIssuerSigningKey = true,
                IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(AppSettings.JWT.SecurityKey))
            };

            var tokenHandler = new JwtSecurityTokenHandler();

            SecurityToken securityToken;

            try
            {
                tokenHandler.ValidateToken(refreshToken, tokenValidationParameters, out securityToken);
                student = SerializeToken(securityToken);

                return true;
            }
            catch (Exception)
            {
                student = null;
                return false;
            }
        }

        public static Student SerializeToken(SecurityToken securityToken)
        {
            Student student = new Student();

            object account;

            (securityToken as JwtSecurityToken).Payload.TryGetValue(ClaimTypes.Name, out account);

            student.Account = account.ToString();

            return student;
        }
    }

    public enum TokenType
    {
        AccessToken,
        RefreshToken
    }

    public class JwtDto
    {
        public string AccessToken { get; set; }
        public string RefreshToken { get; set; }
    }

AppSettings

   public class AppSettings
   {
        private static readonly IConfigurationRoot configuration;

        static AppSettings()
        {
            configuration = new ConfigurationBuilder()
                               .SetBasePath(Directory.GetCurrentDirectory())
                               .AddJsonFile("appsettings.json", false, true)
                               .Build();
        }

        public static class JWT
        {
            public static string Issuer => configuration["JWT:Issuer"];
            public static string AccessTokenAudience => configuration["JWT:AccessTokenAudience"];
            public static int AccessTokenExpires => Convert.ToInt32(configuration["JWT:AccessTokenExpires"]);
            public static string RefreshTokenAudience => configuration["JWT:RefreshTokenAudience"];
            public static int RefreshTokenExpires => Convert.ToInt32(configuration["JWT:RefreshTokenExpires"]);
            public static string SecurityKey => configuration["JWT:SecurityKey"];
        }
    }

appsettings.json

   "JWT": {
    "Issuer": ".Net Core Api",
    "AccessTokenAudience": "AccessToken Client",
    "AccessTokenExpires": 1200,
    "RefreshTokenAudience": "RefreshToken Client",
    "RefreshTokenExpires": 86400,
    "SecurityKey": "5bGx5LicLea1juWugS3msbbkuIrljr8t5ZCR5L+u6aOe"
  }

ConfigureServices

    public void ConfigureServices(IServiceCollection services)
    {
        services.AddControllers();
        services.AddSwaggerGen(options =>
        {
            options.SwaggerDoc("v1", new OpenApiInfo
            {
                Version = "v1",
                Title = "Core",
            });

            var security = new OpenApiSecurityScheme
            {
                Description = "JWT授权,请输入 Bearer {Token} 进行身份验证",
                Name = "Authorization",
                In = ParameterLocation.Header,
                Type = SecuritySchemeType.ApiKey
            };
            options.AddSecurityDefinition("oauth2", security);
            options.AddSecurityRequirement(new OpenApiSecurityRequirement { { security, new List<string>() } });
            options.OperationFilter<AddResponseHeadersFilter>();
            options.OperationFilter<AppendAuthorizeToSummaryOperationFilter>();
            options.OperationFilter<SecurityRequirementsOperationFilter>();
        });

        services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
                .AddJwtBearer(options =>
                    {
                        options.TokenValidationParameters = new TokenValidationParameters
                        {
                            ValidateIssuer = true,
                            ValidIssuer = AppSettings.JWT.Issuer,
                            ValidateAudience = true,
                            ValidAudience = AppSettings.JWT.AccessTokenAudience,
                            ValidateLifetime = true,
                            ClockSkew = TimeSpan.FromSeconds(0),
                            ValidateIssuerSigningKey = true,
                            IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(AppSettings.JWT.SecurityKey))
                        };

                        options.Events = new JwtBearerEvents
                        {
                            OnChallenge = async context =>
                            {
                                context.HandleResponse();
                                context.Response.ContentType = "application/json;charset=utf-8";
                                context.Response.StatusCode = StatusCodes.Status200OK;

                                var result = new Response<string>()
                                {
                                    Status = 401,
                                    Msg = "Unauthorized"
                                };

                                await context.Response.WriteAsync(result.ToJson());
                            }
                        };
                    });
    }

Configure

    app.UseAuthentication();

相关资料

  1. demo
posted @ 2020-07-19 22:22  仿佛若有光;  阅读(645)  评论(0编辑  收藏  举报