locked
Session data getting lost after data being posted on page. RRS feed

  • Question

  • User-1374873858 posted

    I have an ecommerce app in dotnet core 2.2 For the customer's to make their payments they have to be redirected to a bank's secure page where they will enter their card number ccv etc. After that they are being redirected to one of me sites pages depending on the result of the payment. If they payment is complete or failed I am getting some data according to the payment posted to my page  via a post method. When the payment is cancelled i am not getting any data at all. If the user cancels the payment he returns to the PaymentCancel page and everything is just fine. But when the payment is somehow complete (either successful or not) my session data(where i have stored some crucial about the order data such as items or billing address) is lost. Why am i getting this behavior? What am i missing?

    Friday, April 10, 2020 9:24 PM

All replies

  • User-474980206 posted

    The post message is from the bank and will not have session (well it won’t be the clients) The client redirect back to your Site should include the session cookie, unless the redirect path does not match the session cookie path.

    just use the browsers network  debugger to what is happening.

    Saturday, April 11, 2020 1:03 AM
  • User-1374873858 posted

    Could it be possible that the problem comes from the fact that the bank is redirecting the user to my site? This is what I got in the network tab that you suggested.

    Name    Status      Type     Initiator

    PaymentSuccess 302 x-www-form-urlencoded paycenter.piraeusbank.gr/Redirection/(S(5mij1fmu55mgto2sqmm0yhri))/ResultPages/Results.aspx?Success:301
    Login?ReturnUrl=%2FCart%2FPaymentSuccess 200 document /Cart/PaymentSuccess
    Saturday, April 11, 2020 7:59 AM
  • User-854763662 posted

    Hi ___Kout,

    Check whether the session-related configuration has been added to the ConfigureServices method and Configure method in startup.cs

    And you could refer to the below links which may be helpful:

    https://stackoverflow.com/questions/55814347/asp-net-core-2-2-session-lost-after-redirect

    https://stackoverflow.com/questions/49770491/session-variable-value-is-getting-null-in-asp-net-core/50425129#50425129

    Best Regards,

    Sherry

    Monday, April 13, 2020 8:23 AM
  • User-1374873858 posted

    Hi Sherry,

    I have already checked this articles on stackoverflow and tried what has been suggested in them. But nothing seems to work. I forgot to mention that even my user is logged out after he is redirected back to my site. That means that the identity cookie is also being cleared. I saw at the network tab in chrome that there is an attribute "set-cookie". Does this have any meaning at all? Is there a possibility of validation tokens messing up my app?

    Monday, April 13, 2020 10:34 AM
  • User475983607 posted

    Cookies are deterministic and work exactly as written.  Session uses a cookie to ID the user's Session.  I suspect you have other issues with your code that we cannot see.  Can you share how and when you are setting Session?  Is Session really lost or just not populated as expected?

    Monday, April 13, 2020 2:43 PM
  • User-1374873858 posted

    Hello mgebhard,

    Thank you for your reply. The thing is that when i manually redirect to the success page everything works as expected but when i get redirected from the bank's page everything is lost. Here is where I populate the session.

    Session.SetString(_billingAddressSessionKey, JsonConvert.SerializeObject(billingAddressEntity));
                        
                        Session.SetString(_orderSessionKey, JsonConvert.SerializeObject(orderEntity));

    This is how i retrieve it.

    var billingAddressEntity = JsonConvert.DeserializeObject<BillingAddress>(Session.GetString(_billingAddressSessionKey));
                    var orderEntity = JsonConvert.DeserializeObject<Order>(Session.GetString(_orderSessionKey));

    Also, as I have mentioned above, the user is logged out when he gets redirected back to my site( that means that the identity session also gets lost) . I am using AspNetCore.Identity for the user management.

    This is the AddSession in my Startup.cs file

    services.AddSession(options =>
                {
                    options.IdleTimeout = TimeSpan.FromMinutes(60);
                    options.Cookie.Name = ".LarissaClean.Session";
                    options.Cookie.IsEssential = true;
                    options.IOTimeout = TimeSpan.FromMinutes(180);
                });

    Monday, April 13, 2020 3:14 PM
  • User475983607 posted

    You shared how to fundamentally set and configure Session.  Most likely the problem is elsewhere in your code or flow that we cannot see.   For example, setting Session in HTTPS but redirecting to HTTP.   

    Monday, April 13, 2020 4:11 PM
  • User-1374873858 posted
    Yes I have thought about this.. But if that is what is happening why on the cancel button (user being redirected to my paymentcancel page) the cart item, login etc are all as I left them??
    Monday, April 13, 2020 5:41 PM
  • User475983607 posted

    Yes I have thought about this.. But if that is what is happening why on the cancel button (user being redirected to my paymentcancel page) the cart item, login etc are all as I left them??

    I have no idea and I cannot see your code or reproduce this issue.  Can you share sample code that reproduces this issue?

    Monday, April 13, 2020 6:03 PM
  • User-1374873858 posted

    I can't because the bank's page is in the middle.. And there are secret credentials that I sent to their api so I can get to the payment page.. I could show you my controller if that would help
    Monday, April 13, 2020 6:08 PM
  • User475983607 posted

    ___Kout

    I can't because the bank's page is in the middle.. And there are secret credentials that I sent to their api so I can get to the payment page..

    You don't have to use the bank's page.  Just mock the functionality using another web site on a different port.

    It's impossible to solve a problem without being able to reproduce the problem.  The back site cannot expire your cookies.   

    Monday, April 13, 2020 6:12 PM
  • User-1374873858 posted
    I didn't exactly understand what you said I should..
    Monday, April 13, 2020 6:19 PM
  • User-1374873858 posted

    I 've modified my code to make a post to my own page <form action="https://www.mydomain.gr/cart/paymentsuccess" method="POST"> and when i tested it i got the same behavior. After that i removed the "www." from the action in the form and everything worked fine. I am really confused

    Wednesday, April 15, 2020 12:29 PM
  • User475983607 posted

    Sounds like a site and/or cookie configuration issue.  Perhaps you just need to set the cookie domain to mydomain.com.

    https://developer.mozilla.org/en-US/docs/Web/HTTP/Cookies

    Again, the community cannot see your code site configuration, the URLs...

    Wednesday, April 15, 2020 12:50 PM
  • User-1374873858 posted
    public void ConfigureServices(IServiceCollection services)
            {
                services.Configure<CookiePolicyOptions>(options =>
                {
                    // This lambda determines whether user consent for non-essential cookies 
                    // is needed for a given request.
                    options.CheckConsentNeeded = context => true;
                    options.MinimumSameSitePolicy = SameSiteMode.None;
                });
    
                services.AddDbContext<ApplicationDbContext>(options =>
                    options.UseSqlServer(Configuration.GetConnectionString("DefaultConnection")));
    
                services.Configure<IdentityOptions>(options =>
                {
                    options.Password.RequireDigit = false;
                    options.Password.RequiredLength = 4;
                    options.Password.RequireNonAlphanumeric = false;
                    options.Password.RequireUppercase = false;
                    options.Password.RequireLowercase = false;
                });
    
                services.AddIdentity<ApplicationUser, IdentityRole>()
                   .AddEntityFrameworkStores<ApplicationDbContext>()
                   .AddDefaultTokenProviders();
    
    
                services.Configure<AdminAccount>(
                    Configuration.GetSection("AdminAccount"));
    
                services.Configure<UserAccount>(
                    Configuration.GetSection("UserAccount"));
    
                services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_1);
                services.AddDistributedMemoryCache();
    
                services.ConfigureApplicationCookie(options =>
                {
                    options.Cookie.Expiration = TimeSpan.FromMinutes(60);
                    options.SlidingExpiration = false;
                });
    
                services.AddSession(options =>
                {
                    options.Cookie.Domain = "mydomain.gr";
                    options.IdleTimeout = TimeSpan.FromMinutes(60);
                    options.Cookie.Name = ".mydomain.gr.Session";
                    options.Cookie.IsEssential = true;
                    options.IOTimeout = TimeSpan.FromMinutes(180);
                    options.Cookie.HttpOnly = false;
                });
    
                // Add application services.
                services.AddScoped(typeof(IRepository<>), typeof(Repository<>));
                services.AddTransient<IBillingAddressService, BillingAddressService>();
                services.AddTransient<ICategoryService, CategoryService>();
                services.AddTransient<IImageManagerService, ImageManagerService>();
                services.AddTransient<IManufacturerService, ManufacturerService>();
                services.AddTransient<IOrderService, OrderService>();
                services.AddTransient<IProductService, ProductService>();
                services.AddTransient<IReviewService, ReviewService>();
                services.AddTransient<ISpecificationService, SpecificationService>();
                services.AddTransient<IBankService, Infrastructure.Services.Sale.BankService>();
    
                services.AddTransient<IOrderCountService, OrderCountService>();
                services.AddTransient<IVisitorCountService, VisitorCountService>();
    
                services.AddTransient<IContactUsService, ContactUsService>();
    
                // singleton
                services.AddSingleton(sp => MapperConfiguration.CreateMapper());
                services.AddSingleton<ViewHelper>();
                services.AddSingleton<DataHelper>();
                services.AddSingleton<IFileProvider>(HostingEnvironment.ContentRootFileProvider);
    
    
            }
    
            // This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
            public void Configure(IApplicationBuilder app, IHostingEnvironment env)
            {
                if (env.IsDevelopment())
                {
                    app.UseDeveloperExceptionPage();
                    app.UseDatabaseErrorPage();
                    app.UseBrowserLink();
                }
                else
                {
                    app.UseExceptionHandler("/Home/Error");
                    var options = new RewriteOptions().AddRedirectToHttpsPermanent();
                    app.UseRewriter(options);
                }
    
                app.UseImageResize();
                app.UseStaticFiles();
                app.UseCookiePolicy();
                app.UseStatusCodePages();
                app.UseAuthentication();
                app.UseSession();
                app.UseVisitorCounter();
                app.UseMvc(routes =>
                {
                    routes.MapRoute(
                        name: "areaRoute",
                        template: "{area:exists}/{controller}/{action}/{id?}",
                        defaults: new { controller = "Dashboard", action = "Index" });
    
                    routes.MapRoute(
                        name: "productInfo",
                        template: "Product/{seo}",
                        defaults: new { controller = "Home", action = "ProductInfo" });
    
                    routes.MapRoute(
                        name: "category",
                        template: "Category/{category}",
                        defaults: new { controller = "Home", action = "ProductCategory" });
    
                    routes.MapRoute(
                        name: "manufacturer",
                        template: "Manufacturer/{manufacturer}",
                        defaults: new { controller = "Home", action = "ProductManufacturer" });
    
                    routes.MapRoute(
                        name: "productSearch",
                        template: "search/{name?}",
                        defaults: new { controller = "Home", action = "ProductSearch" });
    
                    routes.MapRoute(
                        name: "create review",
                        template: "CreateReview/{id}",
                        defaults: new { controller = "Home", action = "CreateReview" });
    
                    routes.MapRoute(
                        name: "default",
                        template: "{controller=Home}/{action=Index}/{id?}");
                });

    This is my Startup configuration

    Wednesday, April 15, 2020 1:02 PM
  • User246961209 posted

    Did you ever find a solution to this issue.  I'm experiencing a very similar behavior with a .NET Core 3.1 web application.

    Friday, July 17, 2020 1:24 PM