.net core 2.0 JWT 令牌
Posted
技术标签:
【中文标题】.net core 2.0 JWT 令牌【英文标题】:.net core 2.0 JWT token 【发布时间】:2019-01-21 00:02:16 【问题描述】:我有一个使用 .net core 2.0 构建的 Web Api 和一个使用 xamarin 构建的移动应用程序。要登录移动应用程序,请通过传递(用户名和密码)调用 web api。如果凭证是有效的 Web Api,则返回一个 JWT 令牌。该移动应用程序具有一项功能,即使您关闭应用程序(例如(facebook、Instagram 等)),用户也可以保持登录状态。
问题是:
-
如何在用户登录之前保持 JWT 令牌有效
应用程序无需再次询问他/她的登录凭据以给他/她
另一个有效的 JWT 令牌?
用户决定注销后如何让JWT令牌失效
来自应用程序?
【问题讨论】:
【参考方案1】: // This code tested with dotnet core 2.1 ( WebApi + Jwt ) with sample structure
//为你的项目添加一个类Auth
public static class Auth
private static string salt = "jnyanendra_sethi"; // u can chose any key satisfying the length
private static int timeoutInMinute = 1;
private static string _issuer = "http://localhost:5000";
private static string _audience = "http://localhost:5000";
//Generate Token
public static string GenerateToken(Customer customer, List<SupplierInfo> lstSpplierInfo)
var securitykey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(salt));
var credential = new SigningCredentials(securitykey, SecurityAlgorithms.HmacSha256);
// var suppliers = any json string e.g. ["SupplierId":1001,"SupplierName":"RateHawk","SupplierId":1002,"SupplierName":"Hotelbeds"]
var suppliers = JsonConvert.SerializeObject(lstSpplierInfo);//"ur json object to store in claim";
var claims = new List<Claim>
new Claim("CustomerName", customer.CustomerName),
new Claim("Suppliers",suppliers )
;
var mytoken = new JwtSecurityToken(issuer: _issuer, audience: _audience,
claims: claims, notBefore: DateTime.Now, expires: DateTime.Now.AddMinutes(timeoutInMinute), signingCredentials: credential);
var tokenValue = new JwtSecurityTokenHandler().WriteToken(mytoken);
return tokenValue;
//Validate token
public static void ValidateJwtToken(this IServiceCollection services)
var securitykey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(salt));
var credential = new SigningCredentials(securitykey, SecurityAlgorithms.HmacSha256);
var tokenParam = new TokenValidationParameters
ValidateIssuerSigningKey = true,
ValidIssuer = _issuer,
ValidAudience = _audience,
ValidateIssuer = true,
ValidateAudience = true,
RequireSignedTokens = true,
IssuerSigningKey = credential.Key,
ClockSkew = TimeSpan.FromMinutes(timeoutInMinute)
;
services.AddAuthentication(
options =>
options.DefaultScheme = JwtBearerDefaults.AuthenticationScheme;
)
.AddJwtBearer(
options =>
options.TokenValidationParameters = tokenParam;
);
[Route("api/[controller]")]
[ApiController]
public class HotelController : ControllerBase
[HttpGet("Search")]
public SearchReponse Search()// u can take search parameters for input
// based on apikey or username, call db for first time
// get customername / supplierinfo from db
Customer customer = new Customer() CustomerId = "CUS001", CustomerName = "TestCust" ;// dummy
if (customer == null)
this.HttpContext.Response.StatusCode = 401;
return new SearchReponse()
ErrorInfo = new ErrorInfo()
Code = "0",
Description = "No Customer Found"
;
string token = Auth.GenerateToken(customer, GetDummyDataToStoreInClaim());
SearchReponse reponse = new SearchReponse()
GeneralInfo = new GeneralInfo()
Token = token,
Duration = 0
,
Hotels = "Hotels Data",
;
return reponse;
[Authorize]
[HttpGet("Get/id")]
public ActionResult<string> Get(int id)
//// Getting the data stored in claim that required for further process
var CustomerName = HttpContext.User.Identities.FirstOrDefault().Claims.FirstOrDefault(x => x.Type == "CustomerName").Value;
var strSuppliers = HttpContext.User.Identities.FirstOrDefault().Claims.FirstOrDefault(x => x.Type == "Suppliers").Value;
return CustomerName;
我用过的型号:
public class SearchReponse
public GeneralInfo GeneralInfo get; set;
public ErrorInfo ErrorInfo get; set;
public string Hotels get; set;
public class GeneralInfo
public string Token get; set;
public long Duration get; set;
public class ErrorInfo
public string Code get; set;
public string Description get; set;
在 Startup.cs 中
public void ConfigureServices(IServiceCollection services)
services.ValidateJwtToken();
services.AddAuthorization(Options =>
Options.DefaultPolicy = new AuthorizationPolicyBuilder(JwtBearerDefaults.AuthenticationScheme).RequireAuthenticatedUser().Build();
);
services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_1);
--
【讨论】:
【参考方案2】:如何在用户登录应用程序之前保持 JWT 令牌有效 无需再次询问他/她的登录凭据即可给他/她 另一个有效的 JWT 令牌?
您可以设置令牌到期日期并对其进行跟踪。
如果您缩短到期时间并不断刷新令牌到期,直到用户注销。 您可以保存某种无效令牌的黑名单,以便进行验证。用户决定退出应用后,如何让 JWT 令牌失效?
更新:
JWT 由 Header、Payload 和 Signature 组成。您可以阅读有关它的所有内容here 在有效负载中,您可以设置一个名为:“exp”的声明。
The docs: “exp”(过期时间)声明标识过期时间 或者在此之后,JWT 不得被接受处理。这 处理“exp”声明需要当前日期/时间 必须早于“exp”声明中列出的到期日期/时间。
另外,在研究澄清我的答案时,我发现了这个 SO 答案:JSON Web Token expiration。
【讨论】:
通过说“您可以设置令牌到期日期并跟踪该日期。”你的意思是刷新令牌?以上是关于.net core 2.0 JWT 令牌的主要内容,如果未能解决你的问题,请参考以下文章
具有用户权限的基于 JWT 令牌的授权 Asp.net core 2.0