我想保存我的刷新令牌,但它不起作用。我在用户模型上分配 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,并且当用户登录时我正在更新数据库。
据我了解,您有时使用变量
user
作为静态类变量,有时作为局部变量。这很令人困惑,可能是问题的一部分。
您似乎隐藏了
user
方法中的 Login()
变量(这是 DbContext 中的用户对象),但 SetRefreshToken
似乎向静态 user
赋值
只需尝试删除以下行:
public static User user = new User();
并将本地
user
变量从 Login()
传递到 SetRefreshToken
顺便说一句:身份验证并不像看起来那么简单。使用经过测试的库来完成此任务可能是一个更好的主意。