asp.net 如何将刷新令牌保存到.Net7上的数据库

vxf3dgd4  于 5个月前  发布在  .NET
关注(0)|答案(1)|浏览(68)

我想保存我的刷新令牌,但它不工作.我assigning string.Empty on user model and I am working on when user logged in update to database.我认为刷新令牌生成器工作正常,因为我可以看到刷新令牌在我的浏览器的cookie. Can you help me?
以下是我的用户模型:

namespace BackendAuth.Models
{
    public class User
    {
        public int Id { get; set; }
        public string Name { get; set; } = string.Empty;
        public string Surname { get; set; } = string.Empty;
        public string Email { get; set; }
        public bool EmailConfirmed { get; set; } = false;
        public string PasswordHash { get; set; }
        public string RefreshToken { get; set; } = string.Empty;
        public DateTime TokenCreated { get; set; }
        public DateTime TokenExpires { get; set; }
    }
}

字符串
以下是我的刷新令牌模型:

namespace BackendAuth.Models
{
    public class RefreshToken
    {
        public required string Token { get; set; }
        public DateTime Created { get; set; } = DateTime.Now;
        public DateTime Expired { get; set; }
    }
}


这是我的控制器:

using BackendAuth.Data;
using BackendAuth.Dto;
using BackendAuth.Models;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Microsoft.IdentityModel.Tokens;
using System.IdentityModel.Tokens.Jwt;
using System.Security.Claims;
using System.Security.Cryptography;
using System.Text;

namespace BackendAuth.Controllers
{
    [Route("api/[controller]")]
    [ApiController]
    public class UserAuthController : ControllerBase
    {
        public static User user = new User();
        private readonly AppDbContext _context;
        private readonly IConfiguration _configuration;

        public UserAuthController(AppDbContext context, IConfiguration configuration)
        {
            _context = context;
            _configuration = configuration;
        }

        [HttpPost("register")]
        public ActionResult<User> Register(UserDto userDto)
        {
            string passwordHash = BCrypt.Net.BCrypt.HashPassword(userDto.Password);
            
            var user = new User
            {
                Name = userDto.Name,
                Surname = userDto.Surname,
                Email = userDto.Email,
                PasswordHash = passwordHash
            };
            
            _context.Users.Add(user);
            _context.SaveChanges();

            return Ok(user);
        }

        [HttpPost("login")]
        public ActionResult<User> Login(UserLoginDto userLoginDto)
        {
            var user = _context.Users.SingleOrDefault(x => x.Email == userLoginDto.Email);

            if (user == null)
            {
                return BadRequest("User not Found");
            }

            if (!BCrypt.Net.BCrypt.Verify(userLoginDto.Password, user.PasswordHash))
            {
                return BadRequest("Wrong Password");
            }

            string token = CreateToken(user);

            var refreshToken = GenerateRefreshToken();
            SetRefreshToken(refreshToken);
            return Ok(token);
        }

        private RefreshToken GenerateRefreshToken()
        {
            var refreshToken = new RefreshToken
            {
                Token = Convert.ToBase64String(RandomNumberGenerator.GetBytes(64)),
                Expired = DateTime.Now.AddDays(30)
            };

            return refreshToken;
        }

        private void SetRefreshToken(RefreshToken newRefreshToken)
        {
            var cookieOptions = new CookieOptions
            {
                HttpOnly = true,
                Expires = newRefreshToken.Expired
            };
            Response.Cookies.Append("refreshToken", newRefreshToken.Token, cookieOptions);

            if (string.IsNullOrEmpty(user.RefreshToken))
            {
                // Eğer kullanıcının RefreshToken alanı boş ise, veritabanına ekleyin
                user.RefreshToken = newRefreshToken.Token;
            }
            else
            {
                // Eğer kullanıcının RefreshToken alanı dolu ise, mevcut değeri güncelleyin
                user.RefreshToken = newRefreshToken.Token;
                user.TokenCreated = newRefreshToken.Created;
                user.TokenExpires = newRefreshToken.Expired;
            }

            try
            {
                _context.SaveChanges();
            }
            catch (Exception ex)
            {
                // Hata durumunda konsola hata mesajını yazdırabilirsiniz
                Console.WriteLine($"SaveChanges Error: {ex.Message}");
                // İsterseniz hatayı başka bir şekilde ele alabilirsiniz
            }

        }
         
        private string CreateToken(User user)
        {
            List<Claim> claims = new List<Claim>
            {
                new Claim(ClaimTypes.NameIdentifier, user.Id.ToString())
            };

            var key = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(
                _configuration.GetSection("JwtConfig:Secret").Value!));

            var cred = new SigningCredentials(key, SecurityAlgorithms.HmacSha512Signature);

            var token = new JwtSecurityToken(
                    claims: claims,
                    expires: DateTime.Now.AddDays(1),
                    signingCredentials: cred
                );
            var jwt = new JwtSecurityTokenHandler().WriteToken(token);
            return jwt;
        } 

    }
}


我想保存我的刷新令牌,但它不工作。我assigning string.Empty on user model and I am working on when user logged in update to database.

k5hmc34c

k5hmc34c1#

据我所知,你有时候把变量user用作静态类变量,有时候用作局部变量,这很令人困惑,可能是问题的一部分。
您似乎隐藏了Login()方法(来自DbContext的用户对象)中的user变量,但SetRefreshToken似乎将值赋值给静态user
请尝试删除以下行:

public static User user = new User();

字符串
并将本地user变量从Login()传递到SetRefreshToken

  • 只是作为一个侧记:身份验证并不像它看起来那么微不足道。使用经过测试的库来完成此任务可能是一个更好的主意。*

相关问题