Reputation: 712
I am saving session variable in login page,
Guid sessionId = Guid.NewGuid();
HttpContext.Session.SetString("sessionId",sessionId.ToString());
Response.Cookies.Append("sessionId", sessionId.ToString());
Now I access this variable like this:
string sessionId = Request.Cookies["sessionId"];
if (!String.IsNullOrEmpty(sessionId) && sessionId.Equals(HttpContext.Session.GetString("sessionId")))
{
return RedirectToPage("/LoggedIn/Index");
}
return Page();
This code I use on the same razor page (login page) in which session Id is declared, however if I use the above code in any other razor view page, I cannot access this session variable. It is only accessible on the same page it was saved.
What can I possibly be doing wrong ?
Upvotes: 2
Views: 14114
Reputation: 128
I do not recommend using Session Variable for security reasons. However, if you need to store data between sessions but ViewBag is not sufficient, I recommend building your own based on the logged in user and store it in the database:
data.SetGUIDsessionVariable(User.Identity.Name, ThingToStore);
string ThingThatWasStored = data.GetGUIDsessionVariable(User.Identity.Name);
If you cannot use the login name, then use a unique "session variable" GUID instead of the User Identity Name. Either way is fine:
Guid id = Guid.NewGuid()
The way Session variables work is not secure and (quite frankly) is made deliberately (and excessively) difficult and impractical in Razor. Query strings are not secure either. But storing them in the database based on an internal username or random GUID is quite secure.
You're welcome. Writing the code for SetGUIDsessionVariable() ad GetGUIDsessionVariable() is left up to you. I did it in SQL Server but Entity Framework should be possible also.
Upvotes: 0
Reputation: 4267
I had to change the entire context of my previous comment. Here is the "Correct Answer".
Just make sure you have checked below steps:
services.AddDistributedMemoryCache()
memory is configured for caching.services.AddSession()
you've configured session.app.UseSession()
must be called after app.UseCookiePolicy()
and before app.UseMvc()
.**Note that a RedirectToPage()
call does not affect/change session variables at all. **
These steps look basic but actually step 3 is the answer you're looking for. Your code looks absolutely fine.
Here's the Middleware Ordering as outlined by Rick Anderson and Steve Smith https://learn.microsoft.com/en-us/aspnet/core/fundamentals/middleware/index?view=aspnetcore-2.2#order
Sometimes the problem might be caused by CheckConsentNeeded = context => true
being set to true when you configure your CookiePolicyOptions. Just set it to false if you have <CookiePolicyOptions>
configured. If you want to leave it as true you must then configure cookie
and set Cookie.IsEssential = true;
Then the session will survive any redirect action.
Upvotes: 9
Reputation: 30065
You need storage for session data. You can use the memory cache for most applications. You enable it with services.AddMemoryCache()
in the ConfigureServices method. See https://www.learnrazorpages.com/razor-pages/session-state
Upvotes: 0
Reputation: 1187
You should configure your HttpContextAccessor and Session in Startup.cs first.
//ConfigureServices
services.AddHttpContextAccessor();
services.AddSession(s => s.IdleTimeout = TimeSpan.FromMinutes(30));
and
//Configure
app.UseSession();
Then you can access HttpContext on IHttpContextAccessor anywhere. I've set session in Index action.
public class HomeController : Controller
{
private readonly IHttpContextAccessor _httpContextAccessor;
public HomeController(IHttpContextAccessor httpContextAccessor)
{
_httpContextAccessor = httpContextAccessor;
}
public IActionResult Index()
{
_httpContextAccessor.HttpContext.Session.SetString("session1", Guid.NewGuid().ToString());
return View();
}
}
And accessed it in About.cshtml
@using Microsoft.AspNetCore.Http
@inject IHttpContextAccessor HttpContextAccessor
<h1>Session Value:</h1>
<p>@HttpContextAccessor.HttpContext.Session.GetString("session1")</p>
Hope this helps.
Upvotes: 0
Reputation: 2494
I believe you need to use Context.Session.TryGetValue
as opposed to HttpContext
in .Net Core
You will need the @using Microsoft.AspNetCore.Http;
namespace in your view
Upvotes: 0