用户token,也可以利用第三方框架生成,JMS也包含了自己的token服务器。
Token的生成原理:
部署TokenServer
到这里下载 tokenserver.zip,然后部署运行TokenServer。
微服务中编写Login函数
引用 JMS.Token nuget包
代码如下:
/// <summary> /// 登陆系统 /// </summary> /// <param name="userName">用户名</param> /// <param name="password">密码</param> /// <returns>用户token</returns> public string Login(string userName,string password) { //假设用户登陆成功,id为888 var userid = 888; var tokenClient = new TokenClient("192.168.40.132", 9911); var token = tokenClient.BuildLongWithExpire(userid, DateTime.Now.AddMinutes(15));return token; } /// <summary> /// 刷新token /// </summary> /// <returns>新的用户token</returns> [JMS.Authorize]
public string RefreshToken()
{
var tokenClient = new TokenClient("192.168.40.132", 9911);
var token = tokenClient.BuildLongWithExpire((long)this.UserContent, DateTime.Now.AddMinutes(15));
return token;
}
Program.cs中,启用JMS.Token作为身份验证
services.UseJmsTokenAuthentication(AuthorizationContentType.Long, "192.168.40.132", 9911,"auth");
Controller中,如果所有方法要求身份验证,才能调用,那么,在Controller上加上 [JMS.Authorize] 标识,如果只是某些方法要求身份验证,那么,在方法上加 [JMS.Authorize] 标识
上面代码展示了如何生成一个最短的token,如果你想在token里面放更多的信息,可以使用TokenClient.BuildForString函数生成。不过,有userid和过期时间足矣了,因为token需要每次都放在头部传输,太长只会增加网络流量。
客户端访问微服务时,把token放在header里面
using ( var tran = CreateMST() ) { tran.SetHeader("auth", token); .......
AspNet中使用JMS.Token验证
nuget 引用 JMS.Token.AspNetCore
public void ConfigureServices(IServiceCollection services) { services.AddJmsTokenAuthentication(JMS.Token.AspNetCore.TokenContentType.Longs, "127.0.0.1", 9911); services.AddControllers(); }
public void Configure(IApplicationBuilder app, IWebHostEnvironment env) { if (env.IsDevelopment()) { app.UseDeveloperExceptionPage(); } app.UseRouting(); //启用身份验证 app.UseAuthentication(); app.UseAuthorization(); app.UseEndpoints(endpoints => { endpoints.MapControllers(); }); }
Controller中获取身份信息:[Authorize]为标准的AspNet [Authorize],不是JMS.Authorize
[Authorize] [HttpGet] public string Test() { return this.User.FindFirstValue("Content"); }
JS端token解码,获取过期时间
//解码string类型的token function decodeJmsStringToken(token) { var str = window.atob(token); var strArr = JSON.parse(str); var obj = JSON.parse(strArr[0]); var expireTime = new Date(new Date(1970, 0, 1).getTime() + obj.e * 1000); return { content: obj.d, expireTime: expireTime }; } //解码long类型的token function decodeJmsLongToken(token) { var raw = window.atob(token); var rawLength = raw.length; var array = new Uint8Array(new ArrayBuffer(rawLength)); for (var i = 0; i < rawLength; i++) { array[i] = raw.charCodeAt(i); } var expireTime = 0; if (!expireTime) { var timeArr = array.slice(10, 18); for (var i = 0; i < 4; i++) { expireTime = expireTime | ((timeArr[i] & 0xFF) << (i * 8)); } expireTime = new Date(new Date(1970, 0, 1).getTime() + expireTime * 1000); } return { expireTime: expireTime }; }