question

AfaqKanwarMuhammad-6424 avatar image
0 Votes"
AfaqKanwarMuhammad-6424 asked BrandoZhang-MSFT answered

Postman request does not keep session value in .net core

I am new in .net core so I tried to keep user session after login. My Auth class is responsible to do that when I hit the login request through postman HttpContext accessor works fine and values are saved in the session like Auth.userId = 1 but when I send request to othr endpoints Auth.userId = 0 I don't know how it happen behind that

Here is my Auth Class
public static class Auth
{

     private static IHttpContextAccessor _accessor;
    
     public static void SetSessionWrapper(IHttpContextAccessor accessor)
     {
         _accessor = accessor;
     }
    
     public static int UserId => _accessor.HttpContext.Session.GetId("UserId").Value;
    
     public static string Email => _accessor.HttpContext.Session.GetString("Email").ConvertToString();
    
     public static bool IsLogin => _accessor.HttpContext.Session.GetBoolean("IsLogin").ConvertToBool();
    
     public static string OrganizationType => _accessor.HttpContext.Session.GetString("OrganizationType");
    
     public static int OrganizationId => _accessor.HttpContext.Session.GetId("OrganizationId").Value;
    
       
 }

and after the login here I create User session

 public class UserRepository : Repository<User, FundingPlatformContext>, IUserRepository
 {
    
     private readonly FundingPlatformContext _context;
     private readonly IHttpContextAccessor _httpContextAccessor;
     private readonly AppSettings _appSettings;
    
     public UserRepository(FundingPlatformContext context, IHttpContextAccessor httpContextAccessor, IOptions<AppSettings> appSettings) : base(context)
     {
         _context = context;
         _httpContextAccessor = httpContextAccessor;
         _appSettings = appSettings.Value;
     }
   public async Task<LoginResponseDto> CreateUserSession(LoginDto loginDto)
     {
         var currentUser = await GetUserByEmailAndOrganizationKey(loginDto.Email, loginDto.OrganizationKey);
    
         var loginResponse = new LoginResponseDto();
    
         if (currentUser == null || !currentUser.IsActive)
         {
             loginResponse.Message = "User does not active with this email and organization key";
             return loginResponse;
         }
    
         if (await CheckFailedLoginCount(currentUser.Id))
         {
             loginResponse.Message = "You cannot log in because your user has been locked. Please click on Forgot password or Change password.";
             currentUser.IsActive = false;
    
             await _context.SaveChangesAsync();
    
             return loginResponse;
         }
    
         try
         {
             string encPwd = EncryptDecryptHelper.Encrypt(loginDto.Password);
             var userDetail = await _context.Users.Include(q => q.FpUserRoles).ThenInclude(r => r.Roles).Include(o => o.Organization).FirstOrDefaultAsync(e => e.Email == loginDto.Email && e.Organization.OrganizationKey == loginDto.OrganizationKey && e.PasswordHash == encPwd);
    
             if (userDetail != null)
             {
                 _httpContextAccessor.HttpContext.Session.SetBoolean("IsLogin", true);
                 _httpContextAccessor.HttpContext.Session.SetId("UserID", userDetail.Id);
                 _httpContextAccessor.HttpContext.Session.SetString("Email", userDetail.Email);
                 _httpContextAccessor.HttpContext.Session.SetId("OrganizationId", userDetail.Organization.Id);
                 _httpContextAccessor.HttpContext.Session.SetString("OrganizationType", userDetail.Organization.OrganizationType);
                 _httpContextAccessor.HttpContext.Session.SetBoolean("IsActive", true);
                  
                 // TODO Maybe save whole serialized userobject in session?
    
                 loginResponse.Message = "User logged in successfully!";
    
                 userDetail.FailedLoginCount = 0;
                 userDetail.IsActive = true;
    
                 await _context.SaveChangesAsync();
                 return loginResponse;
             }
             else
             {
                 currentUser.FailedLoginCount += 1;
    
                 loginResponse.Message = "Invalid user name or password.";
    
                 await _context.SaveChangesAsync();
                 return loginResponse;
             }
         }
           
         catch (Exception ex)
         {
             loginResponse.Message = "Error Occurred: " + ex.Message;
             return null;
         }
     }
 }

In Controller Auth.isLogin returns false even it sets to true after login

 public async Task<IActionResult> Login(LoginDto loginData)
     {
         try
         {
             if (Auth.IsLogin) return Ok("user already login");
    
               
             var loginResponse = await _unitOfWork.User.CreateUserSession(loginData);
             if (loginResponse.Token == null)
             {
                 return Unauthorized(loginResponse);
             }
    
             return Ok(loginResponse);
                    
         
         }
         catch (Exception ex)
         {
             return StatusCode(500, new ErrorDto(ex.Message));
         }
     }

here is the stratup class

 public void ConfigureServices(IServiceCollection services)
     {
         try
         {
             _log.Info("[ConfigureServices] LogicApi");
    
             var connectionString = Configuration.GetValue<string>("ConnectionStrings:FundingPrograms");
    
             _log.Info("[ConfigureServices] connectionString " + connectionString);
             services.AddDistributedMemoryCache();
    
             services.AddSession(options =>
             {
                 options.IdleTimeout = TimeSpan.FromSeconds(10);
                 options.Cookie.HttpOnly = true;
                 options.Cookie.IsEssential = true;
             });
             services.AddHttpContextAccessor();
             var serviceProvider = services.BuildServiceProvider();
             var accessor = serviceProvider.GetService<IHttpContextAccessor>();
             Auth.SetSessionWrapper(accessor);
             services.AddDbContext<FundingPlatformContext>(options => options.UseSqlServer(connectionString, x => x.MigrationsAssembly("FundingPlatform.Data")));
             services.AddScoped<IUnitOfWork, UnitOfWork>();
    
             services.AddControllers();
    
                
         }
         catch (Exception x)
         {
             _log.Error("[ConfigureServices] Failed", x);
         }
     }
dotnet-aspnet-core-generaldotnet-aspnet-core-mvcdotnet-aspnet-core-webapi
· 1
5 |1600 characters needed characters left characters exceeded

Up to 10 attachments (including images) can be used with a maximum of 3.0 MiB each and 30.0 MiB total.

Session is stored on the server. The user's Session key is stored in a cookie. Your Postman app or process must send the Session cookie after a successful authentication. Postman will not do this for you, see Postman support for more information.

0 Votes 0 ·

1 Answer

BrandoZhang-MSFT avatar image
0 Votes"
BrandoZhang-MSFT answered

Hi AfaqKanwarMuhammad-6424,

Since the postman will not keep the session inside the cookie, you should get the session id and then store it and put it inside the postman , then it will work well.

Details, you could refer to below steps:

1.Send the request to the server to get the session id.

121126-capture.png

2.Set the cookie value

121104-image.png

Please notice, you should set the right domain for the cookie. If you are debug by using VS, the localhost will be the right domain.

121142-image.png

3.Then send the request to the server and it will work well.



capture.png (19.5 KiB)
image.png (12.9 KiB)
image.png (34.5 KiB)
5 |1600 characters needed characters left characters exceeded

Up to 10 attachments (including images) can be used with a maximum of 3.0 MiB each and 30.0 MiB total.