笔记源于课堂编写:BiliBili
源视频教程:https://www.bilibili.com/video/BV1Ex411d7Mx
一、前期系统立项
1.1-技术选型

1.2-用例需求


1.3-数据库分析

//后期其他表:血型、省市区、学历、章节、知识点、
二、跨域/JWT身份验证/统一返回
笔记源于课堂编写:BiliBili
源视频教程:https://www.bilibili.com/video/BV1z4411u7rE?p=2
2.1-Core
2.1.1-测试:使用JS请求,然后出现这个错误:
<script>get();function get(){var xhr = new XMLHttpRequest();xhr.open("GET", "http://localhost:52704/api/Cors/GetHello", true);xhr.setRequestHeader("Content-type","application/x-www-form-urlencoded");xhr.send();}</script>
2.1.2-如何解决(环境:.NET COre 3.1—.NET5好像不行)
(1)在【Startup.cs】的【ConfigureServices】方法中注册一下。
readonly string MyAllowSpecificOrigins = "_myAllowSpecificOrigins";//解决跨域services.AddCors(options => {options.AddPolicy(MyAllowSpecificOrigins, bulder =>bulder.AllowAnyOrigin().AllowAnyMethod().AllowAnyHeader().AllowCredentials());});
(2)在【Startup.cs】的【Configure】方法中使用跨域即可。
 //主要就是这两行,但是要注意,这一行要在app.UseRouting 和 UseEndpoints 之间             app.UseRouting();             
 //主要就是这两行,但是要注意,这一行要在app.UseRouting 和 UseEndpoints 之间
            app.UseRouting();
            app.UseCors(MyAllowSpecificOrigins);
            app.UseAuthorization();
            app.UseEndpoints(endpoints =>
            {
                endpoints.MapControllers();
            });
        }
2.2-JWT身份验证+统一返回
(1)JWT封装
 public class JwtTool
{
        /// <summary>
        /// Key
        /// </summary>
        public readonly static string secret = "sadfasdfasdfasdfasdfasdfasdfasdeqwtrqwetreth";
        /// <summary>
        /// 加密
        /// </summary>
        /// <param name="payload"></param>
        /// <param name="key"></param>
        /// <returns></returns>
        public static string Encode(Dictionary<string, object> payload, string key) {
            //不要泄露
            //var secret = "sadfasdfasdfasdfasdfasdfasdfasdeqwtrqwetreth";
            IJwtAlgorithm algorithm = new HMACSHA256Algorithm();
            IJsonSerializer serializer = new JsonNetSerializer();
            IBase64UrlEncoder urlEncoder = new JwtBase64UrlEncoder();
            IJwtEncoder encoder = new JwtEncoder(algorithm, serializer, urlEncoder);
            var token= encoder.Encode(payload, secret);
            return token;
        }
        /// <summary>
        /// 解密-校验
        /// </summary>
        /// <param name="token"></param>
        /// <param name="key"></param>
        /// <returns></returns>
        public static string Decoding(string token, string key) 
        {
            try
            {
                IJwtAlgorithm algorithm = new HMACSHA256Algorithm();
                IJsonSerializer serializer = new JsonNetSerializer();
                IDateTimeProvider provider = new UtcDateTimeProvider();
                IJwtValidator validator = new JwtValidator(serializer, provider);
                IBase64UrlEncoder urlEncoder = new JwtBase64UrlEncoder();
                IJwtDecoder decoder = new JwtDecoder(serializer, validator, urlEncoder, algorithm);
                var json = decoder.Decode(token, key, verify: true);
                return "解密成功:" + json;
            }
            catch (TokenExpiredException)
            {
                return "Token 已经过期!";
            }
            catch (SignatureVerificationException)
            {
                return "签名校验失败,数据可能被篡改!";
            }
        }
    }
(2)封装一个校验JWT方法
public static string ValideLogined(HttpRequest req)
{
    //不要泄露
    //var secret = "sadfasdfasdfasdfasdfasdfasdfasdeqwtrqwetreth";
    var keys = req.Headers.Keys;
    string token = "";
    foreach (var key in keys)
    {
        if (key == "token")
        {
            token = key;
        }
    }
    if (token == "") {
        throw new Exception("请登录!");
    }
    else
    {
        return JwtTool.Decoding(req.Headers["token"].ToString(), JwtTool.secret);
    }
}
(3)登录后生成一个Token(WebAPI)
/// <summary>
/// 登录
/// </summary>
/// <param name="loginName"></param>
/// <param name="pwd"></param>
/// <returns></returns>
[HttpGet]
[Route("Login")]
public string Login(string loginName, string pwd) 
{ 
   if(loginName=="admin"  && pwd == "admin")
   {
      //返回token
       var token = JwtTool.Encode(new Dictionary<string, object>() 
          { { "loginName", loginName } }, JwtTool.secret);
       return token;
   }
    else
    {
        throw new Exception("账号或者密码有误!");
    }
}
(4)做别的操作时,校验是否传了合法的Token。
        /// <summary>
        /// 获取用户资料
        /// </summary>
        /// <param name="logingName"></param>
        /// <returns></returns>
        [Route("GetUserInfo")]
        [HttpGet]
        public string GetUserInfo()
        {
            var username=LoginTool.ValideLogined(Request);
            return "【用户资料】"+ username;
        }
