Skip to content

Instantly share code, notes, and snippets.

@HugoVG
Created July 23, 2022 14:59
Show Gist options
  • Save HugoVG/6c5439dd71bffd518cb6d80f0b95de36 to your computer and use it in GitHub Desktop.
Save HugoVG/6c5439dd71bffd518cb6d80f0b95de36 to your computer and use it in GitHub Desktop.
Json web tokens, JWT, for C# API,
public interface IJWTStore
{
Tokens Authenticate(LoginUser users); //This is a small Model of just Username Password you can make your own
string GetNameFromToken(string token);
}
public class JTWStore : IJWTStore
{
private readonly APIContext _context; // This is your DBContext
public JTWStore(APIContext context) //Dependancy Inject your DB context
{
_context = context;
}
public Tokens Authenticate(LoginUser users)
{
var user = _context.Users.Any(x => x.name == users.UserName && x.password == users.Password);
if (!user) //So we don't give a token to a person that doesn't exist
return null;
User user1 = _context.Users.FirstOrDefault(x => x.name == users.UserName && x.password == users.Password)!;
// Else we generate JSON Web Token
var tokenHandler = new JwtSecurityTokenHandler(); //Makes JWT handler
var tokenKey = Encoding.UTF8.GetBytes("<<Your Secret>>");
var claims = new List<Claim>();
claims.Add(new Claim(ClaimTypes.Name, user1.Id.ToString())); //You can also use the Name of the person
claims.Add(new Claim(ClaimTypes.NameIdentifier, user1.Id.ToString())); //You can also use the Name of the person
var tokenDescriptor = new SecurityTokenDescriptor
{
Subject = new ClaimsIdentity(claims.ToArray()),
Expires = DateTime.UtcNow.AddDays(10), //Put this higher for a longer valid Token
SigningCredentials = new SigningCredentials(new SymmetricSecurityKey(tokenKey), SecurityAlgorithms.HmacSha256Signature)
};
var token = tokenHandler.CreateToken(tokenDescriptor);
return new Tokens { Token = tokenHandler.WriteToken(token) };
}
//Gets the name of who's token it is from
//Sometimes nice to know who's who so you don't retrieve a TON of data
//just to validate someone's existance
public string GetNameFromToken(string token)
{
token = token.ToString().Replace("Bearer ", "");
var tokenKey = Encoding.UTF8.GetBytes("<<Your Secret>>");
var handler = new JwtSecurityTokenHandler();
var validations = new TokenValidationParameters
{
ValidateIssuerSigningKey = true,
IssuerSigningKey = new SymmetricSecurityKey(tokenKey),
ValidateIssuer = false,
ValidateAudience = false
};
var claims = handler.ValidateToken(token, validations, out var tokenSecure);
return claims.Identity.Name;
}
}
//A small class to make it easer to send JSON data via API
public class LoginUser
{
public string UserName { get; set; }
public string Password { get; set; }
}
//Inside the builder
builder.Services.AddAuthentication(x =>
{
x.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;
x.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme;
}).AddJwtBearer(o =>
{
var Key = Encoding.UTF8.GetBytes("<<Your Secret>>"); //don''t post this on public github
o.SaveToken = true;
o.TokenValidationParameters = new TokenValidationParameters
{
ValidateIssuer = false,
ValidateAudience = false,
ValidateLifetime = true,
ValidateIssuerSigningKey = true,
ValidIssuer = "<<Your Name>>",
ValidAudience = "<<Random Audience Keyword>>",
IssuerSigningKey = new SymmetricSecurityKey(Key)
};
});
builder.Services.AddSingleton<IJWTStore, JWTStore>(); // We will use this to validate and send tokens
//Rest of the builder
var app = builder.Build();
app.UseAuthentication(); //This is so people can authenticate
app.UseAuthorization(); //this is so you can use [Authorize]
//A small class for users, obviously yours will be bigger,
public class User
{
public int Id { get; set; }
public string? name { get; set; }
public string? email { get; set; }
public string? password { get; set; }
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment