房产中介管理软件第10课:整合JWT

一、引用Microsoft.AspNetCore.Authentication.JwtBearer

二、在appsettings.json文件中新增关于jwt的设置

//Jwt配置
  "JwtSettings": {
    //是否启用
    "IsEnabled": true,
    //加密密钥
    "SecurityKey": "3Qianji,weiyouXiangsibUkE!",
    //签发者
    "Issuer": "FangAdmin",
    //使用者
    "Audience": "FangAdminUsers",
    //默认用户名
    "DefaultUser": "FangAdmin",
    //默认密码
    "DefaultPassword": "!Qaz@wSx3Dce",
    //盐有效时间,单位:秒
    "SaltExpiration": "10",
    //token有效时间,单位:分钟
    "TokenExpiration": "20"
  }

新增JwtSetting.cs类文件,参考以前文章关于全局类的配置,startup里读取jwtsetting并赋值给globalcontext.jwtsetting

三、配置startup.cs里的方法

ConfigureServices里:

#region 注册系统全局Jwt认证
if (GlobalContext.JwtSettings.IsEnabled)
{
    services.AddAuthentication(options =>
    {
        options.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;
        options.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme;
        options.DefaultScheme = JwtBearerDefaults.AuthenticationScheme;
    }).
    AddJwtBearer(options =>
    {
        options.Events = new JwtBearerEvents
        {
            OnAuthenticationFailed = context =>
            {
                if (context.Exception.GetType() == typeof(SecurityTokenExpiredException))
                {
                    context.Response.Headers.Add("act", "expired");
                }
                return Task.CompletedTask;
            }
        };

        options.SaveToken = true;
        options.RequireHttpsMetadata = false;

        options.TokenValidationParameters = new Microsoft.IdentityModel.Tokens.TokenValidationParameters()
        {
            ValidateIssuerSigningKey = true,
            ValidIssuer = GlobalContext.JwtSettings.Issuer,
            ValidAudience = GlobalContext.JwtSettings.Audience,
            IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(GlobalContext.JwtSettings.SecurityKey)),
            ValidateIssuer = true,
            ValidateAudience = true,
            ValidateLifetime = true,
            RequireExpirationTime = true,
            ClockSkew = TimeSpan.FromSeconds(30)
        };
    });
}

#endregion

Configure方法新增use,注意有先后顺序

// 启用认证
app.UseAuthentication();

// 授权中间件
app.UseAuthorization();

四、登录的时候写入

string guid = Guid.NewGuid().ToString("N");
var claims = new[] {
    new Claim(JwtRegisteredClaimNames.Jti, guid),
    new Claim(ClaimTypes.NameIdentifier, modagent.AgentID.ToString()),
    new Claim(ClaimTypes.Name, modagent.AgentName),
    new Claim(ClaimTypes.MobilePhone, modagent.Telephone),
    new Claim("DeptID", modagent.DeptID.ToString()),
    new Claim("DeptName", ""),
    new Claim("PositionID", modagent.PositionID.ToString()),
    new Claim("PositionName", ""),
    new Claim("RoleID", modagent.RoleID.ToString()),
    new Claim("RoleName", ""),
    new Claim("AgentPhoto", StringUtil.TrimString(modagent.AgentPhoto)),
};

var key = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(GlobalContext.JwtSettings.SecurityKey));
var credentials = new SigningCredentials(key, SecurityAlgorithms.HmacSha256);
var jwtToken = new JwtSecurityToken(
    GlobalContext.JwtSettings.Issuer,
    GlobalContext.JwtSettings.Audience,
    claims,
    expires: DateTime.Now.AddMinutes(GlobalContext.JwtSettings.TokenExpiration),
    signingCredentials: credentials);

var token = new JwtSecurityTokenHandler().WriteToken(jwtToken);

五、前端页面获取并写入本地,每次axios请求携带token信息

 登录成功后把jwt信息写入到cookies,并设置过期时间

const that = this;
// 加载数据
httpPost(that,'登录',API.LOGIN, userInfo).then(res => 
{  
   if (res.data.code != 2000) { return; }    
                
   const {user, token, expireAt} = res.data.data

   //设置用户及登录信息
   commit('setUserInfo', user)

   // 设置授权
   setAuth({token: token, expireAt: new Date(expireAt)})

   resolve();
}).catch(error => {
   reject(error)
})

当退出登录的时候清空jwt信息

const that = this;
// 加载数据
httpPost(that,'退出',API.LOGOUT, {}).then(res => 
{  
    if (res.data.code != 2000) { return; }    
                
    //删除用户的登录信息
    commit('removeUserInfo')

    // 取消授权
    removeAuth()

    resolve();
}).catch(error => {
    reject(error)
}) 

axios里新增拦截器,每次请求的时候附加上jwt信息

// 配置拦截器
axios.interceptors.request.use(config => {
  config.headers.Authorization = Cookie.get(tokenName);
  return config
});

六、后端页面验证前端提交的token信息

 先建立一个MyHttpContext文件

public static class MyHttpContext
    {
        public static IServiceProvider ServiceProvider;
        public static Microsoft.AspNetCore.Http.HttpContext Current
        {
            get
            {
                object factory = ServiceProvider.GetService(typeof(Microsoft.AspNetCore.Http.IHttpContextAccessor));
                Microsoft.AspNetCore.Http.HttpContext context = ((Microsoft.AspNetCore.Http.HttpContextAccessor)factory).HttpContext;
                return context;
            }
        }
    }

在startup中绑定并赋值

//注册httpcontext
services.AddSingleton<IHttpContextAccessor, HttpContextAccessor>();
//赋值httpcontext
MyHttpContext.ServiceProvider = app.ApplicationServices;

就可以调用获取jwt token信息了

public class UserInfoUtil
    {
        /// <summary>
        /// 获得令牌
        /// </summary>
        public static string Token
        {
            get
            {
                try
                {
                    var request = MyHttpContext.Current.Request;
                    var token = StringUtil.TrimString(request.Headers["Authorization"]).Replace("undefined", "").Replace(" ", "");

                    if (token.StartsWith("Bearer"))
                        token = token.Substring(6);

                    return token;
                }
                catch (Exception ex)
                {
                    Console.WriteLine("Token:" + ex.ToString());
                }
                return null;
            }
        }

    }

通过UserInfoUtil.Token就可以快捷获取Token信息了。

 其他相关信息可以从Payload中获取

// 得到 token 中payload部分的值
var handler = new JwtSecurityTokenHandler();
var jwtToken = handler.ReadJwtToken(token);
var payload = jwtToken.Payload;
var claims = payload.Claims;
var AgentID = NumberUtil.GetValue(claims.First(claim => claim.Type == "AgentID").Value);

(本文完)

 

posted @ 2022-09-28 16:47  RandyTech  阅读(43)  评论(0编辑  收藏  举报