Odpowiedź @WeiXiao nie jest najlepsza moim zdaniem. Tutaj odpytujesz bazę danych na podstawie wartości z JWT. Trochę to bez sensu o ten odczyt, który tak naprawdę zupełnie niczego nie robi, tylko bez sensu odpytuje bazę. Rzeczy w tokenie też nie są jawne. One są zakodowane. Dodatkowo token ma krótki czas życia. Dlatego też nie obawiałbym się, że ktoś pozna id. Co za różnica, czy pozna id, czy login? Ja ładuję normalnie Id do tokena. W kodzie autora jednak jest inna rzecz dużo bardziej niepokojąca. A mianowicie - jeśli będę zalogowany, mogę sam sobie nabić tyle skilla, że w ciągu minuty zostanę mistrzem świata. Wystarczy, że cały czas będę wywoływał tę stronę z przeglądarki :) I to trzeba w jakiś sposób zabezpieczyć. Tu jest też cały wachlarz możliwości.
A teraz krótki kodzik do tokena, bo to nie jest na początku takie oczywiste:
W taki sposób możesz stworzyć JWT:
async Task<JwtSecurityToken> CreateDefaultToken(SystemUser user)
{
IList<Claim> userClaims = await signInManager.UserManager.GetClaimsAsync(user); //pobierasz claimsy z bazy
IList<string> userRoles = await signInManager.UserManager.GetRolesAsync(user); //i role
List<Claim> claims = new Claim[] //dodajesz kilka nowych claimsów
{
new Claim(JwtRegisteredClaimNames.Jti, Guid.NewGuid().ToString()), //Id samego tokena
new Claim(JwtRegisteredClaimNames.Email, user.Email), //e-mail usera
new Claim(ClaimTypes.Name, user.UserName), //nazwa usera
new Claim(ClaimTypes.NameIdentifier, user.Id.ToString()) //Id usera
}.Union(userClaims).ToList(); //łączysz z odczytanymi claimsami
foreach (string role in userRoles)
claims.Add(new Claim(ClaimTypes.Role, role)); //dodajesz role
var key = tokenReader.GetSecureKey(config["Auth:JwtBearer:Key"]);
var creds = new SigningCredentials(key, SecurityAlgorithms.HmacSha256);
var token = new JwtSecurityToken(
issuer: config["Auth:JwtBearer:Issuer"],
audience: config["Auth:JwtBearer:Audience"],
claims: claims,
expires: DateTime.Now.AddMinutes(5),
signingCredentials: creds);
return token;
}
//GetSecureKey u mnie wygląda tak:
public SymmetricSecurityKey GetSecureKey(string key)
{
return new SymmetricSecurityKey(Encoding.UTF8.GetBytes(key));
}
I masz wtedy wszystko w HttpContext.User.
Pamiętaj tylko, że powinieneś tworzyć też RefreshToken, który ma dłuższy czas życia.
Zasada jest taka:
- tworzysz JWT i refreshtoken.
- JWT powinien żyć krótki (5 - 15 minut); refresh żyje dłużej (godzinę, dzień...)
- typ identyfikuje się za pomocą JWT
gdy JWT wygasa:
- umieszczasz go w specjalnej tabeli, np. blacklisted_tokens
- nie powinien już być używany
- posługujesz się refresh tokenem, żeby wydać nowy JWT. Przy okazji wydajesz nowy refresh token
- jeśli nie możesz wydać nowego JWT, bo np. refresh token też wygasł, no to dupa. User musi się zalogować.