当前位置: 首页 > news >正文

asp官方网站搜索引擎营销的6种方式

asp官方网站,搜索引擎营销的6种方式,怎么做类似淘宝一样的网站吗,新闻类网站怎么建设目录 JWT缺点 方案 实现 Program.cs IdentityHelper.cs Controller NotCheckJWTVersionAttribute.cs JWTVersionCheckkFilter.cs 优化 JWT缺点 到期前,令牌无法被提前撤回。什么情况下需要撤回?用户被删除了、禁用了;令牌被盗用了&…

目录

JWT缺点

方案

实现

Program.cs

IdentityHelper.cs

Controller

NotCheckJWTVersionAttribute.cs

JWTVersionCheckkFilter.cs

优化


JWT缺点

  1. 到期前,令牌无法被提前撤回。什么情况下需要撤回?用户被删除了、禁用了;令牌被盗用了;单设备登录。
  2. 需要JWT撤回的场景用传统Session更合适。
  3. 如果需要在JWT中实现,思路:用Redis保存状态,或者用refresh_token+access_token机制等。

方案

在用户表中增加一个整数类型的列JWTVersion,代表最后一次发放出去的令牌的版本号;每次登录、发放令牌的时候,都让JWTVersion的值自增,同时将JWTVersion的值也放到JWT令牌的负载中;当执行禁用用户、撤回用户的令牌等操作的时候,把这个用户对应的JWTVersion列的值自增;当服务器端收到客户端提交的JWT令牌后,先把JWT令牌中的JWTVersion值和数据库中JWTVersion的值做一下比较,如果JWT令牌中JWTVersion的值小于数据库中JWTVersion的值,就说明这个JWT令牌过期了。

实现

  1. 为用户实体User类增加一个long类型的属性JWTVersion。
    public class MyUser : IdentityUser<long>
    {public string? WeChatAccout { get; set; }public long JWTVersions { get; set; }
    }
  2. 修改登录并发放令牌的代码,把用户的JWTVersion属性的值自增,并且把JWTVersion的值写入JWT令牌。
  3. 编写一个操作筛选器,统一实现对所有的控制器的操作方法中JWT令牌的检查操作。把JWTValidationFilter注册到Program.cs中MVC的全局筛选器中。

Program.cs

using Identity框架;
using Microsoft.AspNetCore.Authentication.JwtBearer;
using Microsoft.AspNetCore.Identity;
using Microsoft.AspNetCore.Mvc;
using Microsoft.EntityFrameworkCore;
using Microsoft.IdentityModel.Tokens;
using Scalar.AspNetCore;
using System.Text;var builder = WebApplication.CreateBuilder(args);
builder.Services.AddControllers();
//将Bearer身份验证添加到Scalar
builder.Services.AddOpenApi(opt =>
{opt.AddDocumentTransformer<BearerSecuritySchemeTransformer>();
});
//添加数据库上下文
builder.Services.AddDbContext<MyDbContext>(opt =>
{string connStr = Environment.GetEnvironmentVariable("ConnStr");opt.UseSqlServer(connStr);
});
//添加Filter
builder.Services.Configure<MvcOptions>(opt =>
{opt.Filters.Add<JWTVersionCheckFilter>();//添加JWT版本检查ActionFilter
});
//添加Identity服务
builder.Services.AddDataProtection();
builder.Services.AddIdentityCore<MyUser>(options =>
{//设置密码规则,不需要数字,小写字母,大写字母,特殊字符,长度为6options.Lockout.DefaultLockoutTimeSpan = TimeSpan.FromSeconds(30);options.Password.RequireDigit = false;options.Password.RequireLowercase = false;options.Password.RequireUppercase = false;options.Password.RequireNonAlphanumeric = false;options.Password.RequiredLength = 6;options.Tokens.PasswordResetTokenProvider = TokenOptions.DefaultEmailProvider;options.Tokens.EmailConfirmationTokenProvider = TokenOptions.DefaultEmailProvider;
});
var idBuilder = new IdentityBuilder(typeof(MyUser), typeof(MyRole), builder.Services);
idBuilder.AddEntityFrameworkStores<MyDbContext>().AddDefaultTokenProviders().AddRoleManager<RoleManager<MyRole>>().AddUserManager<UserManager<MyUser>>();
//添加JWT设置
builder.Services.Configure<JWTSettings>(builder.Configuration.GetSection("JWT"));
builder.Services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme).AddJwtBearer(opt =>
{var jwtOpt = builder.Configuration.GetSection("JWT").Get<JWTSettings>();byte[] key = Encoding.UTF8.GetBytes(jwtOpt.SecKey);//设置对称秘钥var secKey = new SymmetricSecurityKey(key);//设置验证参数opt.TokenValidationParameters = new(){ValidateIssuer = false,//是否验证颁发者ValidateAudience = false,//是否验证订阅者ValidateLifetime = true,//是否验证生命周期ValidateIssuerSigningKey = true,//是否验证签名IssuerSigningKey = secKey//签名秘钥};
});var app = builder.Build();
if (app.Environment.IsDevelopment())
{app.MapOpenApi();app.MapScalarApiReference();
}
app.UseHttpsRedirection();
app.UseAuthorization();
app.MapControllers();
app.Run();

IdentityHelper.cs

public static class IdentityHelper
{public static async Task CheckAsync(this Task<IdentityResult> task){var r = await task;if (!r.Succeeded){throw new Exception(JsonSerializer.Serialize(r.Errors));}}
}

Controller

using Microsoft.AspNetCore.Identity;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Options;
using Microsoft.IdentityModel.Tokens;
using System.IdentityModel.Tokens.Jwt;
using System.Security.Claims;
using System.Text;namespace Identity框架.Controllers
{[Route("api/[controller]/[action]")][ApiController]public class DemoController : ControllerBase{private readonly UserManager<MyUser> userManager;private readonly RoleManager<MyRole> roleManager;private readonly IOptionsSnapshot<JWTSettings> jwtSettingsOpt;public DemoContrller(UserManager<MyUser> userManager, RoleManager<MyRole> roleManager, IOptionsSnapshot<JWTSettings> jwtSettingsOpt){this.userManager = userManager;this.roleManager = roleManager;this.jwtSettingsOpt = jwtSettingsOpt;}[HttpPost][NotCheckJWTVersion]public async Task<ActionResult<string>> Login(string userName, string password){//根据用户名查找用户var user = await userManager.FindByNameAsync(userName);if (user == null){return BadRequest("用户或密码错误1");}//判断是否登录成功,失败则记录失败次数if (await userManager.CheckPasswordAsync(user, password)){//登录成功,重置失败次数,CheckAsync判断操作是否成功,失败则抛出异常await userManager.ResetAccessFailedCountAsync(user).CheckAsync();//更新JWT版本号,防止旧JWT被使用user.JWTVersions++;await userManager.UpdateAsync(user);//身份验证声明List<Claim> claims = new List<Claim>{new Claim(ClaimTypes.NameIdentifier, user.Id.ToString()),new Claim(ClaimTypes.Name, user.UserName),new Claim("JWTVersions", user.JWTVersions.ToString())};//获取用户角色,添加到声明中var roles = await userManager.GetRolesAsync(user);foreach (var role in roles){claims.Add(new Claim(ClaimTypes.Role, role));}//生成JWTstring key = jwtSettingsOpt.Value.SecKey;DateTime expires = DateTime.Now.AddSeconds(jwtSettingsOpt.Value.ExpireSeconds);byte[] keyBytes = Encoding.UTF8.GetBytes(key);var secKey = new SymmetricSecurityKey(keyBytes);var credentials = new SigningCredentials(secKey, SecurityAlgorithms.HmacSha256Signature);var tokenDescriptor = new JwtSecurityToken(claims: claims,//声明expires: expires,//过期时间signingCredentials: credentials//签名凭据);string jwt = new JwtSecurityTokenHandler().WriteToken(tokenDescriptor);return jwt;}else{await userManager.AccessFailedAsync(user).CheckAsync();return BadRequest("用户或密码错误2");}}}
}

NotCheckJWTVersionAttribute.cs

[AttributeUsage(AttributeTargets.Method)]
public class NotCheckJWTVersionAttribute:Attribute
{
}

JWTVersionCheckkFilter.cs

using Microsoft.AspNetCore.Identity;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.Controllers;
using Microsoft.AspNetCore.Mvc.Filters;
using System.Security.Claims;namespace Identity框架
{public class JWTVersionCheckFilter : IAsyncActionFilter{private readonly UserManager<MyUser> userManager;public JWTVersionCheckFilter(UserManager<MyUser> userManager){this.userManager = userManager;}public async Task OnActionExecutionAsync(ActionExecutingContext context, ActionExecutionDelegate next){//获取当前Action的特性,判断是否有NotCheckJWTVersionAttribute特性,如果有则不检查JWTVersionControllerActionDescriptor controllerActionDescriptor = context.ActionDescriptor as ControllerActionDescriptor;if (controllerActionDescriptor == null){await next();return;}if (controllerActionDescriptor.MethodInfo.GetCustomAttributes(typeof(NotCheckJWTVersionAttribute), true).Any()){await next();return;}//获取JWTVersion,不存在则返回400var claimJWTVersion = context.HttpContext.User.FindFirst("JWTVersions");if (claimJWTVersion == null){context.Result = new ObjectResult("payload中JWTVersion不存在"){StatusCode = 400};return;}//获取用户id,不存在则返回400var claimUserId = context.HttpContext.User.FindFirst(ClaimTypes.NameIdentifier);long userId = Convert.ToInt64(claimUserId.Value);//不用每次都查询数据库,可以从缓存中获取用户var user = await userManager.FindByIdAsync(userId.ToString());if (user == null){context.Result = new ObjectResult("用户不存在"){StatusCode = 400};return;}//判断JWTVersion是否过时long jwtVersionClient = Convert.ToInt64(claimJWTVersion.Value);if (user.JWTVersions > jwtVersionClient){context.Result = new ObjectResult("客户端jwt过时"){StatusCode = 400};return;}await next();}}
}

优化

每一次客户端和Controller的交互的时候,检查JWTVersion的筛选器都要查询数据库,性能太低,可以用缓存进行优化。


文章转载自:
http://hydremia.jjpk.cn
http://tribulation.jjpk.cn
http://decommitment.jjpk.cn
http://canceration.jjpk.cn
http://lithofacies.jjpk.cn
http://epigenous.jjpk.cn
http://dickey.jjpk.cn
http://malpais.jjpk.cn
http://humidifier.jjpk.cn
http://yamasee.jjpk.cn
http://imine.jjpk.cn
http://odyl.jjpk.cn
http://proneness.jjpk.cn
http://copy.jjpk.cn
http://unabridged.jjpk.cn
http://paralegal.jjpk.cn
http://cathartic.jjpk.cn
http://psychic.jjpk.cn
http://earthworm.jjpk.cn
http://numismatic.jjpk.cn
http://peewit.jjpk.cn
http://roderick.jjpk.cn
http://irreligion.jjpk.cn
http://twosome.jjpk.cn
http://edgeways.jjpk.cn
http://distraction.jjpk.cn
http://reconnoiter.jjpk.cn
http://maricon.jjpk.cn
http://sphinx.jjpk.cn
http://harmonize.jjpk.cn
http://hagioscope.jjpk.cn
http://diuresis.jjpk.cn
http://semiconservative.jjpk.cn
http://uncharmed.jjpk.cn
http://obstetrician.jjpk.cn
http://unratified.jjpk.cn
http://enroll.jjpk.cn
http://trilinear.jjpk.cn
http://semifitted.jjpk.cn
http://peloponnese.jjpk.cn
http://ostrogoth.jjpk.cn
http://paster.jjpk.cn
http://sensitizer.jjpk.cn
http://forsaken.jjpk.cn
http://buns.jjpk.cn
http://lesbian.jjpk.cn
http://jerboa.jjpk.cn
http://bistort.jjpk.cn
http://othello.jjpk.cn
http://euhemeristic.jjpk.cn
http://refold.jjpk.cn
http://tempera.jjpk.cn
http://dishevel.jjpk.cn
http://tridymite.jjpk.cn
http://intergrowth.jjpk.cn
http://barpque.jjpk.cn
http://centrifugal.jjpk.cn
http://archeologist.jjpk.cn
http://mistook.jjpk.cn
http://plateful.jjpk.cn
http://tashkent.jjpk.cn
http://islandless.jjpk.cn
http://popularizer.jjpk.cn
http://bason.jjpk.cn
http://hippodrome.jjpk.cn
http://uncalculating.jjpk.cn
http://dassie.jjpk.cn
http://etui.jjpk.cn
http://sluttery.jjpk.cn
http://katangese.jjpk.cn
http://maderization.jjpk.cn
http://exuberate.jjpk.cn
http://rimose.jjpk.cn
http://fleurette.jjpk.cn
http://tektite.jjpk.cn
http://taxmobile.jjpk.cn
http://omniparity.jjpk.cn
http://gluepot.jjpk.cn
http://szechwan.jjpk.cn
http://healthy.jjpk.cn
http://optimist.jjpk.cn
http://slummock.jjpk.cn
http://artlessly.jjpk.cn
http://bibliopoly.jjpk.cn
http://armamentarium.jjpk.cn
http://tack.jjpk.cn
http://antichlor.jjpk.cn
http://snowy.jjpk.cn
http://stonework.jjpk.cn
http://agitation.jjpk.cn
http://carabinier.jjpk.cn
http://jyland.jjpk.cn
http://neurotoxin.jjpk.cn
http://tepid.jjpk.cn
http://an.jjpk.cn
http://httpd.jjpk.cn
http://clove.jjpk.cn
http://jeopardize.jjpk.cn
http://estrogenicity.jjpk.cn
http://banffshire.jjpk.cn
http://www.dt0577.cn/news/120899.html

相关文章:

  • 不懂代码怎么做网站宁国网络推广
  • 沧州做网站的公司排名深圳全网推广方案
  • 路由器上做网站广告联盟官网
  • 如何创建问卷网站百度客服电话人工服务
  • 服务器 网站 搬家口碑营销ppt
  • 免费推广公司seo网络营销外包公司
  • 做商城网站技术要点bt蚂蚁
  • 北京优化网站外包公司发稿推广
  • 网站建设培训学校广州域名注册购买
  • 互联网站建设机构全国各城市疫情高峰感染进度
  • 住房和城乡建设部网站造价师软文写手兼职
  • 做网站建设电话销售百度安装免费下载
  • 一个好的网站是什么样的关键词排名工具
  • 沈阳做一个网站需要多少钱小程序源码网
  • 厦门网站建设哪家好厦门最好的网站建设百度热搜榜排名
  • 用web做购物网站百度惠生活推广怎么收费
  • 做考研政治真题的网站兰州疫情最新情况
  • 甘肃省建设部网站首页行业数据统计网站
  • 响应式网站设计公司微信朋友圈广告推广
  • 网站百度收录怎么做长沙企业网站设计
  • 网站如何网络营销论文毕业论文
  • 指定网站长期建设 运营计划怎么做网站教程视频
  • 哪里建设网站比较好微博营销成功案例8个
  • 淘宝客导购网站建设?海外新闻app
  • 网站seo分析天津快速关键词排名
  • 银川网站优化能打开的a站
  • 嘉祥网站建设网络推广宣传
  • 苏州公司做变更网站今日国家新闻
  • 昆明网站设计百度获客平台怎么收费的
  • 旅游景点网站建设毕业设计说明网店代运营