|
@@ -10,6 +10,7 @@ using System.Threading.Tasks;
|
|
|
using Azure;
|
|
|
using Azure.Cosmos;
|
|
|
using Microsoft.AspNetCore.Authorization;
|
|
|
+using Microsoft.AspNetCore.Cryptography.KeyDerivation;
|
|
|
using Microsoft.AspNetCore.Mvc;
|
|
|
using Microsoft.Extensions.Options;
|
|
|
using TEAMModelOS.Models;
|
|
@@ -1682,5 +1683,90 @@ namespace TEAMModelOS.Controllers
|
|
|
}
|
|
|
return null;
|
|
|
}
|
|
|
+
|
|
|
+ /// <summary>
|
|
|
+ /// 學生登入
|
|
|
+ /// </summary>
|
|
|
+ /// <param name = "request" ></ param >
|
|
|
+ [AllowAnonymous]
|
|
|
+ [HttpPost("student-login")]
|
|
|
+
|
|
|
+ public async Task<IActionResult> Login(JsonElement request)
|
|
|
+ {
|
|
|
+ var client = _azureCosmos.GetCosmosClient();
|
|
|
+ //參數取得
|
|
|
+ if (!request.TryGetProperty("school_code", out JsonElement school_code)) return BadRequest();
|
|
|
+ if (!request.TryGetProperty("id", out JsonElement id)) return BadRequest();
|
|
|
+ if (!request.TryGetProperty("pw", out JsonElement pw)) return BadRequest();
|
|
|
+
|
|
|
+ var response = await client.GetContainer("TEAMModelOSTemp", "Student").ReadItemStreamAsync(id.GetString(), new PartitionKey($"Base-{school_code.ToString().ToLower()}"));
|
|
|
+
|
|
|
+
|
|
|
+ int error = 0;
|
|
|
+ string message = "帳號或密碼錯誤";
|
|
|
+ string auth_token = "";
|
|
|
+
|
|
|
+ if (response.Status == 200)
|
|
|
+ {
|
|
|
+ using var json = await JsonDocument.ParseAsync(response.ContentStream);
|
|
|
+
|
|
|
+ // 取得資料庫salt
|
|
|
+ json.RootElement.TryGetProperty("salt", out JsonElement salt);
|
|
|
+ // 取得資料庫pw
|
|
|
+ json.RootElement.TryGetProperty("pw", out JsonElement dbpw);
|
|
|
+ // 取得資料庫name
|
|
|
+ json.RootElement.TryGetProperty("name", out JsonElement name);
|
|
|
+
|
|
|
+ var HashedPW = HashedPassword(pw.ToString(), salt.ToString());
|
|
|
+
|
|
|
+ if (dbpw.ToString().Equals(HashedPW.ToString()))
|
|
|
+ {
|
|
|
+ //換取AuthToken,提供給前端
|
|
|
+ auth_token = JwtAuthExtension.CreateAuthToken(_option.HostName, id.GetString(), name.GetString(), "", _option.JwtSecretKey, roles: new[] { "student" });
|
|
|
+ }
|
|
|
+ else
|
|
|
+ {
|
|
|
+ error = 1;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ else
|
|
|
+ {
|
|
|
+ error = 1;
|
|
|
+ }
|
|
|
+
|
|
|
+ if (error > 0)
|
|
|
+ {
|
|
|
+ return Ok(
|
|
|
+ new
|
|
|
+ {
|
|
|
+ error,
|
|
|
+ message
|
|
|
+ }
|
|
|
+ );
|
|
|
+ }
|
|
|
+ else
|
|
|
+ {
|
|
|
+ return Ok(
|
|
|
+ new
|
|
|
+ {
|
|
|
+ error,
|
|
|
+ auth_token
|
|
|
+ }
|
|
|
+ );
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ public static string HashedPassword(string password, string salt)
|
|
|
+ {
|
|
|
+ byte[] hashBytes = KeyDerivation.Pbkdf2(
|
|
|
+ password: password,
|
|
|
+ salt: Encoding.UTF8.GetBytes(salt), // SHA1鹽(8-20字節), SHA256(32字節)
|
|
|
+ prf: KeyDerivationPrf.HMACSHA1,
|
|
|
+ iterationCount: 10000, // hash次數,越多次代表破解難度變高,但效能差點
|
|
|
+ numBytesRequested: 256 / 8 // 指定得出結果長度
|
|
|
+ );
|
|
|
+ String hashText = BitConverter.ToString(hashBytes).Replace("-", string.Empty);
|
|
|
+ return hashText;
|
|
|
+ }
|
|
|
}
|
|
|
}
|