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 = 500;
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"
}
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());
}
};
});
}
app.UseAuthentication();
相关资料
- demo
.NetCore 3.1 JWT AccessToken And RefreshToken