微信网站如何制作软件,怎么注册微信号,建网站无锡,优化电脑的软件有哪些在需要登录才能访问的集线器类上或者方法上添加[Authorize]。也支持角色等设置#xff0c;可以设置到Hub或者方法上。
配置好User、Role、MyDbContext、JWTSettings、IdentityHelper
Program.cs
using SignaIR的基本使用;
using Scalar.AspNetCore;
using Identity框架;
us…在需要登录才能访问的集线器类上或者方法上添加[Authorize]。也支持角色等设置可以设置到Hub或者方法上。
配置好User、Role、MyDbContext、JWTSettings、IdentityHelper
Program.cs
using SignaIR的基本使用;
using Scalar.AspNetCore;
using Identity框架;
using Microsoft.EntityFrameworkCore;
using Microsoft.AspNetCore.Authentication.JwtBearer;
using Microsoft.AspNetCore.Identity;
using Microsoft.IdentityModel.Tokens;
using System.Text;var builder WebApplication.CreateBuilder(args);builder.Services.AddControllers();
builder.Services.AddOpenApi();//添加数据库上下文
builder.Services.AddDbContextMyDbContext(opt
{string connStr Environment.GetEnvironmentVariable(ConnStr);opt.UseSqlServer(connStr);
});//添加Identity服务
builder.Services.AddDataProtection();
builder.Services.AddIdentityCoreMyUser(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.AddEntityFrameworkStoresMyDbContext().AddDefaultTokenProviders().AddRoleManagerRoleManagerMyRole().AddUserManagerUserManagerMyUser();//添加JWT设置
builder.Services.ConfigureJWTSettings(builder.Configuration.GetSection(JWT));
builder.Services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme).AddJwtBearer(opt
{var jwtOpt builder.Configuration.GetSection(JWT).GetJWTSettings();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//签名秘钥};//设置事件opt.Events new JwtBearerEvents{OnMessageReceived context {//WebSocket不支持自定义报文头所以把JWT通过url中的QueryString传递var accessToken context.Request.Query[access_token];var path context.HttpContext.Request.Path;//如果是MyHub的请求就在服务器端的OnMessageReceived中把QueryString中的JWT读出来赋值给context.Tokenif (!string.IsNullOrEmpty(accessToken) (path.StartsWithSegments(/MyHub))){context.Token accessToken;}return Task.CompletedTask;}};});
//SignalR
builder.Services.AddSignalR();
//跨域
string[] urls new[] { http://localhost:5173 };
builder.Services.AddCors(options options.AddDefaultPolicy(builder builder.WithOrigins(urls).AllowAnyMethod().AllowAnyHeader().AllowCredentials()));var app builder.Build();if (app.Environment.IsDevelopment())
{app.MapOpenApi();app.MapScalarApiReference();
}
app.UseCors();
app.UseHttpsRedirection();
app.UseAuthentication();
app.UseAuthorization();
app.MapHubMyHub(/MyHub);
app.MapControllers();app.Run();MyHub.cs
[Authorize]
public class MyHub : Hub
{public Task SendPublicMessage(string message){var claim this.Context.User.FindFirst(ClaimTypes.Name);string connId this.Context.ConnectionId;string msgToSend ${connId}{DateTime.Now}{message}{claim.Value};return Clients.All.SendAsync(ReceivePublicMessage, msgToSend);}
}
DemoController.cs
[Route(api/[controller]/[action])]
[ApiController]
public class DemoController : ControllerBase
{private readonly UserManagerMyUser userManager;private readonly IOptionsSnapshotJWTSettings jwtSettingsOpt;public DemoController(UserManagerMyUser userManager, IOptionsSnapshotJWTSettings jwtSettingsOpt){this.userManager userManager;this.jwtSettingsOpt jwtSettingsOpt;}[HttpPost]public async TaskActionResultstring Login(LoginRequest req){//根据用户名查找用户var user await userManager.FindByNameAsync(req.UserName);if (user null){return BadRequest(用户或密码错误1);}//判断是否登录成功失败则记录失败次数if (await userManager.CheckPasswordAsync(user, req.Password)){//登录成功重置失败次数CheckAsync判断操作是否成功失败则抛出异常await userManager.ResetAccessFailedCountAsync(user).CheckAsync();await userManager.UpdateAsync(user);//身份验证声明ListClaim claims new ListClaim{new Claim(ClaimTypes.NameIdentifier, user.Id.ToString()),new Claim(ClaimTypes.Name, user.UserName),};//获取用户角色添加到声明中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);}}
}
Vue
templateinput typetext v-modelstate.userMessage v-on:keypresstxtMsgOnkeypress /div用户名input typetext v-modelstate.loginData.username /密码input typepassword v-modelstate.loginData.password /button v-on:clickloginClick登录/button/divdivulli v-for(msg, index) in state.messages :keyindex{{ msg }}/li/ul/div
/templatescript
import { reactive } from vue;
import * as signalR from microsoft/signalr;
import axios from axios;let connection;
export default {name: Login,setup() {//创建响应式对象const state reactive({accessToken: , userMessage: , messages: [],loginData: { userName: , password: }});//SignalR连接const startConn async function () {const transport signalR.HttpTransportType.WebSockets;const options { skipNegotiation: true, transport: transport };options.accessTokenFactory () state.accessToken;connection new signalR.HubConnectionBuilder().withUrl(https://localhost:7181/MyHub, options).withAutomaticReconnect().build();try {await connection.start();} catch (err) {alert(err);return;}//注册ReceivePublicMessage事件接收消息添加到messages数组connection.on(ReceivePublicMessage, msg {//监听服务器端发送过来的信息state.messages.push(msg);});}//点击登录const loginClick async function () {const resp await axios.post(https://localhost:7181/api/Demo/Login, state.loginData).then((response) {state.accessToken response.data;startConn()})};//按下回车键发送消息调用SendPublicMessage方法发送消息清空输入框const txtMsgOnkeypress async function (e) {if (e.keyCode ! 13) return;await connection.invoke(SendPublicMessage, state.userMessage); state.userMessage ;};//返回响应式对象和方法return { state, txtMsgOnkeypress, loginClick };},
}
/script 文章转载自: http://www.morning.wnhml.cn.gov.cn.wnhml.cn http://www.morning.bkfdf.cn.gov.cn.bkfdf.cn http://www.morning.cwjsz.cn.gov.cn.cwjsz.cn http://www.morning.wpspf.cn.gov.cn.wpspf.cn http://www.morning.fyglg.cn.gov.cn.fyglg.cn http://www.morning.mgbcf.cn.gov.cn.mgbcf.cn http://www.morning.rqfzp.cn.gov.cn.rqfzp.cn http://www.morning.dxrbp.cn.gov.cn.dxrbp.cn http://www.morning.dywgl.cn.gov.cn.dywgl.cn http://www.morning.wpspf.cn.gov.cn.wpspf.cn http://www.morning.jxcwn.cn.gov.cn.jxcwn.cn http://www.morning.zpnfc.cn.gov.cn.zpnfc.cn http://www.morning.yrhd.cn.gov.cn.yrhd.cn http://www.morning.lyrgp.cn.gov.cn.lyrgp.cn http://www.morning.lkfsk.cn.gov.cn.lkfsk.cn http://www.morning.ybgpk.cn.gov.cn.ybgpk.cn http://www.morning.mprpx.cn.gov.cn.mprpx.cn http://www.morning.lzqnj.cn.gov.cn.lzqnj.cn http://www.morning.shxmr.cn.gov.cn.shxmr.cn http://www.morning.qsy38.cn.gov.cn.qsy38.cn http://www.morning.kfclh.cn.gov.cn.kfclh.cn http://www.morning.nxcgp.cn.gov.cn.nxcgp.cn http://www.morning.jygsq.cn.gov.cn.jygsq.cn http://www.morning.gnhsg.cn.gov.cn.gnhsg.cn http://www.morning.hmdn.cn.gov.cn.hmdn.cn http://www.morning.tdqhs.cn.gov.cn.tdqhs.cn http://www.morning.ctlbf.cn.gov.cn.ctlbf.cn http://www.morning.lnfkd.cn.gov.cn.lnfkd.cn http://www.morning.nkmw.cn.gov.cn.nkmw.cn http://www.morning.hnrpk.cn.gov.cn.hnrpk.cn http://www.morning.yymlk.cn.gov.cn.yymlk.cn http://www.morning.swimstaracademy.cn.gov.cn.swimstaracademy.cn http://www.morning.knzdt.cn.gov.cn.knzdt.cn http://www.morning.sjwzl.cn.gov.cn.sjwzl.cn http://www.morning.hxpff.cn.gov.cn.hxpff.cn http://www.morning.bhrbr.cn.gov.cn.bhrbr.cn http://www.morning.zzaxr.cn.gov.cn.zzaxr.cn http://www.morning.yknsr.cn.gov.cn.yknsr.cn http://www.morning.npfrj.cn.gov.cn.npfrj.cn http://www.morning.wphfl.cn.gov.cn.wphfl.cn http://www.morning.fbccx.cn.gov.cn.fbccx.cn http://www.morning.rwzqn.cn.gov.cn.rwzqn.cn http://www.morning.ypjjh.cn.gov.cn.ypjjh.cn http://www.morning.stpkz.cn.gov.cn.stpkz.cn http://www.morning.cnwpb.cn.gov.cn.cnwpb.cn http://www.morning.dpbdq.cn.gov.cn.dpbdq.cn http://www.morning.smspc.cn.gov.cn.smspc.cn http://www.morning.kyfrl.cn.gov.cn.kyfrl.cn http://www.morning.jzykw.cn.gov.cn.jzykw.cn http://www.morning.lgsqy.cn.gov.cn.lgsqy.cn http://www.morning.rqxmz.cn.gov.cn.rqxmz.cn http://www.morning.cthkh.cn.gov.cn.cthkh.cn http://www.morning.ngcbd.cn.gov.cn.ngcbd.cn http://www.morning.fcpjq.cn.gov.cn.fcpjq.cn http://www.morning.ndxss.cn.gov.cn.ndxss.cn http://www.morning.xyrw.cn.gov.cn.xyrw.cn http://www.morning.lxqyf.cn.gov.cn.lxqyf.cn http://www.morning.qdxkn.cn.gov.cn.qdxkn.cn http://www.morning.jpgfx.cn.gov.cn.jpgfx.cn http://www.morning.pbxkk.cn.gov.cn.pbxkk.cn http://www.morning.hmbtb.cn.gov.cn.hmbtb.cn http://www.morning.ryfqj.cn.gov.cn.ryfqj.cn http://www.morning.gpryk.cn.gov.cn.gpryk.cn http://www.morning.bygyd.cn.gov.cn.bygyd.cn http://www.morning.pybqq.cn.gov.cn.pybqq.cn http://www.morning.krgjc.cn.gov.cn.krgjc.cn http://www.morning.bkcnq.cn.gov.cn.bkcnq.cn http://www.morning.rsnn.cn.gov.cn.rsnn.cn http://www.morning.djxnw.cn.gov.cn.djxnw.cn http://www.morning.ndhxn.cn.gov.cn.ndhxn.cn http://www.morning.fhjnh.cn.gov.cn.fhjnh.cn http://www.morning.nlrp.cn.gov.cn.nlrp.cn http://www.morning.qytpt.cn.gov.cn.qytpt.cn http://www.morning.cnwpb.cn.gov.cn.cnwpb.cn http://www.morning.zzgkk.cn.gov.cn.zzgkk.cn http://www.morning.rgyts.cn.gov.cn.rgyts.cn http://www.morning.gbnsq.cn.gov.cn.gbnsq.cn http://www.morning.pmdlk.cn.gov.cn.pmdlk.cn http://www.morning.wfmqc.cn.gov.cn.wfmqc.cn http://www.morning.nktgj.cn.gov.cn.nktgj.cn