各位好,鄙人專案使用 vue+netcore3.1 webapi,在處理登陸驗證碼時,碰到一個比較蛋疼的問題,生成一個驗證碼,并存入session,用swagger直接呼叫登陸介面,能獲取到session,但如果運行vue去跑,HttpContext.Session回傳null,廢話不多說,直接上代碼。
Startup:
public class Startup
{
public IConfiguration Configuration { get; }
public static ILoggerRepository repository { get; set; }
public Startup(IConfiguration configuration)
{
Configuration = configuration;
repository = LogManager.CreateRepository("Bull.Api");
//指定組態檔
XmlConfigurator.Configure(repository, new FileInfo("log4net.config"));
}
public void ConfigureServices(IServiceCollection services)
{
services.AddCors(options =>
{
options.AddPolicy("aa",
builder => builder.AllowAnyOrigin()
.WithMethods("GET", "POST", "HEAD", "PUT", "DELETE", "OPTIONS")
);
});
services.AddSession(options =>
{
options.IdleTimeout = TimeSpan.FromMinutes(30);
options.Cookie.HttpOnly = true;
});
services.AddControllers(options =>
{
options.Filters.Add<GlobalExceptionFilter>();
})
.AddControllersAsServices()
.AddNewtonsoftJson(options =>
{
options.SerializerSettings.ContractResolver = new DefaultContractResolver();
});
services.AddScoped<IHttpContextAccessor, HttpContextAccessor>()
.AddTransient<IActionContextAccessor, ActionContextAccessor>()
.AddSingleton(Configuration)
.AddSingleton<IHttpContextAccessor, HttpContextAccessor>()
.AddLogging()
.Configure<KestrelServerOptions>(options =>
{
options.AllowSynchronousIO = true;
})
.Configure<IISServerOptions>(options =>
{
options.AllowSynchronousIO = true;
})
//.Configure<CookiePolicyOptions>(options =>
//{
// options.CheckConsentNeeded = context => false; // Default is true, make it false
//})
.AddSwaggerGen(c =>
{
c.SwaggerDoc("v1", new OpenApiInfo
{
Version = "v1.0.0",
Title = "介面檔案"
});
// JWT認證
c.AddSecurityDefinition("Bearer", new OpenApiSecurityScheme
{
Scheme = "bearer",
BearerFormat = "JWT",
Type = SecuritySchemeType.Http,
Name = "Authorization",
In = ParameterLocation.Header,
Description = "Authorization:Bearer {your JWT token}<br/><b>授權地址:/Base_Manage/Home/SubmitLogin</b>",
});
c.AddSecurityRequirement(new OpenApiSecurityRequirement
{
{
new OpenApiSecurityScheme{Reference = new OpenApiReference
{
Type = ReferenceType.SecurityScheme,
Id = "Bearer"
}
},
new string[] { }
}
});
// 為 Swagger JSON and UI設定xml檔案注釋路徑
var basePath = Path.GetDirectoryName(typeof(Program).Assembly.Location);//獲取應用程式所在目錄(絕對,不受作業目錄影響,建議采用此方法獲取路徑)
//基礎層
c.IncludeXmlComments(Path.Combine(basePath, "Coldairarrow.Util.xml"));
//物體層
c.IncludeXmlComments(Path.Combine(basePath, "Coldairarrow.Entity.xml"));
//業務邏輯層
c.IncludeXmlComments(Path.Combine(basePath, "Coldairarrow.Business.xml"));
//控制器層
c.IncludeXmlComments(Path.Combine(basePath, "Coldairarrow.Api.xml"), true);
});
//services.AddDistributedMemoryCache().AddSession();
services.AddDistributedMemoryCache();
services.AddMvc();
}
public void ConfigureContainer(ContainerBuilder builder)
{
// 在這里添加服務注冊
var baseType = typeof(IDependency);
//自動注入IDependency介面,支持AOP,生命周期為InstancePerDependency
var diTypes = GlobalData.FxAllTypes
.Where(x => baseType.IsAssignableFrom(x) && x != baseType)
.ToArray();
builder.RegisterTypes(diTypes)
.AsImplementedInterfaces()
.PropertiesAutowired()
.InstancePerDependency()
.EnableInterfaceInterceptors()
.InterceptedBy(typeof(Interceptor));
//注冊Controller
builder.RegisterAssemblyTypes(typeof(Startup).GetTypeInfo().Assembly)
.Where(t => typeof(Controller).IsAssignableFrom(t) && t.Name.EndsWith("Controller", StringComparison.Ordinal))
.PropertiesAutowired();
//AOP
builder.RegisterType<Interceptor>();
}
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
app.UseCookiePolicy();
app.UseSession(); //session 放到最后面就報錯,不知道為什么
//Request.Body重用
app.Use(next => context =>
{
context.Request.EnableBuffering();
return next(context);
})
.UseMiddleware<CorsMiddleware>()//跨域
.UseDeveloperExceptionPage()
.UseStaticFiles(new StaticFileOptions
{
ServeUnknownFileTypes = true,
DefaultContentType = "application/octet-stream"
})
//Swagger配置
.UseSwagger()
.UseSwaggerUI(c =>
{
c.SwaggerEndpoint("/swagger/v1/swagger.json", "1.0.0");
c.RoutePrefix = string.Empty;
})
.UseRouting()
.UseCors("aa")
.UseEndpoints(endpoints =>
{
endpoints.MapControllers();
});
AutofacHelper.Container = app.ApplicationServices.GetAutofacRoot();
InitAutoMapper();
InitId();
ApiLog();
}
private void InitAutoMapper()
{
List<(Type from, Type target)> maps = new List<(Type from, Type target)>();
maps.AddRange(GlobalData.FxAllTypes.Where(x => x.GetCustomAttribute<MapToAttribute>() != null)
.Select(x => (x, x.GetCustomAttribute<MapToAttribute>().TargetType)));
maps.AddRange(GlobalData.FxAllTypes.Where(x => x.GetCustomAttribute<MapFromAttribute>() != null)
.Select(x => (x.GetCustomAttribute<MapFromAttribute>().FromType, x)));
Mapper.Initialize(cfg =>
{
maps.ForEach(aMap =>
{
cfg.CreateMap(aMap.from, aMap.target);
});
});
}
private void InitId()
{
new IdHelperBootstrapper()
//設定WorkerId
.SetWorkderId(ConfigHelper.GetValue("WorkerId").ToLong())
//使用Zookeeper
//.UseZookeeper("127.0.0.1:2181", 200, GlobalSwitch.ProjectName)
.Boot();
}
private void ApiLog()
{
HttpHelper.HandleLog = log =>
{
//介面日志
using (var lifescope = AutofacHelper.Container.BeginLifetimeScope())
{
lifescope.Resolve<ILogger>().Info(LogType.系統跟蹤, log);
}
};
}
}
HomeController下的獲取驗證碼和登陸:
[NoCheckJWT]
[HttpGet]
public async Task<IActionResult> Captcha()
{
string Captcha = HttpContext.Session.GetString("Captcha");
(byte[] imgBytes, string code) VerifyCode = ImgVerifyCodeHelper.BuildVerifyCode(4);
HttpContext.Session.SetString("Captcha", VerifyCode.code);
return new FileContentResult(VerifyCode.imgBytes, "image/jpeg");
}
[EnableCors("aa")]
[HttpPost]
[CheckParamNotEmpty("userName", "password", "captcha")]
[NoCheckJWT]
public async Task<string> SubmitLogin(string userName, string password,string captcha)
{
string Captcha = HttpContext.Session.GetString("Captcha");
if (Captcha != captcha.ToUpper())
{
throw new BusException("驗證碼不正確!"+ Captcha);//除錯用
}
return await _homeBus.SubmitLoginAsync(userName, password);
}
uj5u.com熱心網友回復:
都是呼叫的webapi是吧uj5u.com熱心網友回復:
是的,swagger和postman 先獲取驗證碼,然后再提交登陸,SubmitLogin下的HttpContext.Session都能獲取,vue登陸中就是沒有uj5u.com熱心網友回復:
SessionId了解一下uj5u.com熱心網友回復:
是否可以詳細說一下,應該怎么做uj5u.com熱心網友回復:
是否可以詳細說一下,應該怎么做
uj5u.com熱心網友回復:
你沒搞清楚Session的機制。Session是生成了一個SessionId通過cookie傳到后端,后端才能取出對應的Session。
uj5u.com熱心網友回復:
看下能不能取到COOKIE,你跨域了嗎?跨域是不發COOKIE的轉載請註明出處,本文鏈接:https://www.uj5u.com/net/250870.html
標籤:C#
