From 174a2de4261dc2f4ea89e20a661a6a69475ed45a Mon Sep 17 00:00:00 2001 From: "branislav.radivojevic" Date: Fri, 28 Oct 2022 15:58:37 +0200 Subject: login and register pw encrypt, return jwt --- Backend/Api/Api/Api.csproj | 1 + Backend/Api/Api/Controllers/AuthController.cs | 13 ++++++ Backend/Api/Api/Interfaces/IJwtService.cs | 2 +- Backend/Api/Api/Interfaces/IUserService.cs | 6 +++ Backend/Api/Api/Program.cs | 2 + Backend/Api/Api/Services/JwtService.cs | 5 +-- Backend/Api/Api/Services/UserService.cs | 62 ++++++++++++++++++++++++--- 7 files changed, 82 insertions(+), 9 deletions(-) (limited to 'Backend/Api') diff --git a/Backend/Api/Api/Api.csproj b/Backend/Api/Api/Api.csproj index dc8b264..10faa3e 100644 --- a/Backend/Api/Api/Api.csproj +++ b/Backend/Api/Api/Api.csproj @@ -11,6 +11,7 @@ + diff --git a/Backend/Api/Api/Controllers/AuthController.cs b/Backend/Api/Api/Controllers/AuthController.cs index 456abd9..6727125 100644 --- a/Backend/Api/Api/Controllers/AuthController.cs +++ b/Backend/Api/Api/Controllers/AuthController.cs @@ -33,5 +33,18 @@ namespace Api.Controllers return Ok(); } + [HttpPost("login")] + public async Task> Login([FromBody] Login creds) + { + var id = await _userService.UserIdFromJwt(); + if (id != null) return Forbid(); + + var jwt= await _userService.Login(creds); + if (jwt != null) + { + return Ok(new { token = jwt }); + } + return BadRequest(); + } } } diff --git a/Backend/Api/Api/Interfaces/IJwtService.cs b/Backend/Api/Api/Interfaces/IJwtService.cs index 1a8fb0a..f9e5d5f 100644 --- a/Backend/Api/Api/Interfaces/IJwtService.cs +++ b/Backend/Api/Api/Interfaces/IJwtService.cs @@ -6,7 +6,7 @@ namespace Api.Interfaces { string GenToken(User user); string TokenToId(string token); - public string GenEmailToken(User user); + public string GenEmailToken(string username); public string EmailTokenToId(string token); } } \ No newline at end of file diff --git a/Backend/Api/Api/Interfaces/IUserService.cs b/Backend/Api/Api/Interfaces/IUserService.cs index 8faad45..9e4e3b9 100644 --- a/Backend/Api/Api/Interfaces/IUserService.cs +++ b/Backend/Api/Api/Interfaces/IUserService.cs @@ -11,6 +11,12 @@ namespace Api.Interfaces Task updateUser(User user); Task deleteUser(String email); Task getUserById(string id); + Task RenewToken(string existingToken); + Task Login(Login login); + Task Register(Register register); + Task VerifyUser(string _id); + Task UserIdFromJwt(); + } } diff --git a/Backend/Api/Api/Program.cs b/Backend/Api/Api/Program.cs index 26ed445..4643937 100644 --- a/Backend/Api/Api/Program.cs +++ b/Backend/Api/Api/Program.cs @@ -23,6 +23,8 @@ builder.Services.AddSingleton(s => builder.Services.AddScoped(); builder.Services.AddScoped(); +builder.Services.AddHttpContextAccessor(); + diff --git a/Backend/Api/Api/Services/JwtService.cs b/Backend/Api/Api/Services/JwtService.cs index 37ec88e..e3688de 100644 --- a/Backend/Api/Api/Services/JwtService.cs +++ b/Backend/Api/Api/Services/JwtService.cs @@ -56,13 +56,13 @@ namespace Api.Services } } - public string GenEmailToken(User user) + public string GenEmailToken(string username) { var tokenHandler = new JwtSecurityTokenHandler(); var key = Encoding.ASCII.GetBytes(_config.GetSection("AppSettings:EmailToken").Value); var tokenDescriptor = new SecurityTokenDescriptor { - Subject = new ClaimsIdentity(new[] { new Claim("username", user.username), new Claim("id", user._id) }), + Subject = new ClaimsIdentity(new[] { new Claim("username", username)}), Expires = DateTime.UtcNow.AddMinutes(30), SigningCredentials = new SigningCredentials(new SymmetricSecurityKey(key), SecurityAlgorithms.HmacSha256Signature) }; @@ -90,7 +90,6 @@ namespace Api.Services var jwtToken = (JwtSecurityToken)validatedToken; var username = (jwtToken.Claims.First(x => x.Type == "username").Value.ToString()); return username; - //return jwtToken.Claims.First(x => x.Type == "id").Value; } catch { diff --git a/Backend/Api/Api/Services/UserService.cs b/Backend/Api/Api/Services/UserService.cs index 1260814..7c00c05 100644 --- a/Backend/Api/Api/Services/UserService.cs +++ b/Backend/Api/Api/Services/UserService.cs @@ -1,18 +1,22 @@ using Api.Interfaces; using Api.Models; using MongoDB.Driver; +using Microsoft.AspNetCore.Http; +using System.Security.Claims; namespace Api.Services { public class UserService : IUserService { + private readonly IHttpContextAccessor _httpContext; private readonly IMongoCollection _users; private readonly IJwtService _jwtService; - public UserService(IDatabaseConnection settings, IMongoClient mongoClient, IJwtService jwtService) + public UserService(IDatabaseConnection settings, IMongoClient mongoClient, IJwtService jwtService, IHttpContextAccessor httpContextAccessor) { var database = mongoClient.GetDatabase(settings.DatabaseName); _users = database.GetCollection(settings.UserCollectionName); _jwtService=jwtService; + this._httpContext = httpContextAccessor; } public async Task createUser(User user) @@ -20,8 +24,9 @@ namespace Api.Services if (await _users.Find(x => x.email == user.email).FirstOrDefaultAsync() != null) return -1; //email already exists if (await _users.Find(x => x.username == user.username).FirstOrDefaultAsync() != null) - return -2; //username already exists - + return -2; //username already + // + user.password = hashPassword(user.password); await _users.InsertOneAsync(user); return 1; } @@ -68,6 +73,29 @@ namespace Api.Services return 0; } + private static int difficulty = 10; + + public static String hashPassword(String password) + { + String salt = BCrypt.Net.BCrypt.GenerateSalt(difficulty); + String passwordHash = BCrypt.Net.BCrypt.HashPassword(password, salt); + + return passwordHash; + } + + public static Boolean checkPassword(String plainText, String hash) + { + Boolean verified = false; + + if (hash == null || !hash.StartsWith("$2a$")) + return false; + + verified = BCrypt.Net.BCrypt.Verify(plainText, hash); + + return verified; + + } + public async Task Register(Register register) { if (await _users.FindAsync(x => x.email == register.email && x.verified==true).Result.AnyAsync()) @@ -87,15 +115,18 @@ namespace Api.Services } } } + var user = new User(); user.email = register.email; user.username = register.username; user.name = register.name; user.verified = false; - user.password = register.password; // unhashed for now + user.password = hashPassword(register.password); + user.emailToken = _jwtService.GenEmailToken(user.username); + await _users.InsertOneAsync(user); - return ""; + return "User Registered"; } public async Task VerifyUser(string _id) @@ -118,7 +149,28 @@ namespace Api.Services var user = await getUserById(id); return _jwtService.GenToken(user); + } + public async Task Login(Login login) + { + User user = await _users.FindAsync(x => x.email == login.email).Result.FirstAsync(); // add && x.verified == true after implementing + if(user != null && checkPassword(login.password, user.password)) + { + return _jwtService.GenToken(user); + } + return null; + } + public async Task UserIdFromJwt() + { + string id = null; + if (_httpContext.HttpContext.User.FindFirstValue("id") != null) + { + id = _httpContext.HttpContext.User.FindFirstValue("id").ToString(); + var _id = await _users.FindAsync(x => x._id == id).Result.FirstAsync(); + if (_id == null) + id = null; + } + return id; } } } -- cgit v1.2.3