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

问题描述 投票:0回答:1

我想保存我的刷新令牌,但它不起作用。我在用户模型上分配 string.Empty ,并且当用户登录更新数据库时我正在处理。我认为刷新令牌生成器工作正常,因为我可以在浏览器的 cookie 上看到刷新令牌。你能帮我吗?

这是我的用户模型:

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;
        } 

    }
}

我想保存我的刷新令牌,但它不起作用。我正在用户模型上分配 string.Empty,并且当用户登录时我正在更新数据库。

asp.net authentication asp.net-web-api jwt token
1个回答
0
投票

据我了解,您有时使用变量

user
作为静态类变量,有时作为局部变量。这很令人困惑,可能是问题的一部分。

您似乎隐藏了

user
方法中的
Login()
变量(这是 DbContext 中的用户对象),但
SetRefreshToken
似乎向静态
user

赋值

只需尝试删除以下行:

public static User user = new User();

并将本地

user
变量从
Login()
传递到
SetRefreshToken

顺便说一句:身份验证并不像看起来那么简单。使用经过测试的库来完成此任务可能是一个更好的主意。

© www.soinside.com 2019 - 2024. All rights reserved.