.net core 2.1 基於Jwt的登錄認證


1.新建一個.net core2.1 基於 api 的工程,引用Microsoft.AspNetCore.Authentication.JwtBearer 包

2.新建一個Token的實體類,一個Jwt的基礎類

 public class TokenModel
    {
        /// <summary>
        /// 用戶Id
        /// </summary>
        public long userId { get; set; }
        /// <summary>
        /// 用戶名
        /// </summary>
        public string userCode { get; set; }
        /// <summary>
        /// 手機
        /// </summary>
        public string phone { get; set; }
        /// <summary>
        /// 頭像
        /// </summary>
        public string icon { get; set; }
        /// <summary>
        /// 昵稱
        /// </summary>
        public string userName { get; set; }
        /// <summary>
        /// 身份
        /// </summary>
        public string sub { get; set; }
        /// <summary>
        /// 角色
        /// </summary>
        public string role { get; set; }
    }
TokenModel
 /// <summary>
    /// 基礎配置
    /// </summary>
    public class JwtSettings
    {
        //token是誰頒發的
        public string Issuer { get; set; }
        //token可以給哪些客戶端使用
        public string Audience { get; set; }
        //加密的key
        public string SecretKey { get; set; }
        //過期時間 單位:s
        public string ExpireTime { get; set; }
    }
JwtSettings

3.在Appsetting.json中添加默認值

  "JwtSettings": {
    "Issuer": "NinaMua",
    "Audience": "http://localhost:5000",
    "SecretKey": "NinaMua'sSecretKeyMuaMuaMua",//16位字符以上
    "ExpireTime": "3600" //過期時間||單位:s
  }

4.新建一個類去把在appsetting設定的值變成一個可以全局引用的對象

public class AppSettingsInit
    {
        public static JwtSettings JwtSettings;
        
        /// <summary>
        /// 將配置項的值賦值給屬性
        /// </summary>
        /// <param name="configuration"></param>
        public void Initial(IConfiguration configuration)
        {
            JwtSettings = new JwtSettings();
            JwtSettings.Audience = configuration["JwtSettings:Audience"];
            JwtSettings.Issuer = configuration["JwtSettings:Issuer"];
            JwtSettings.SecretKey = configuration["JwtSettings:SecretKey"];
            JwtSettings.ExpireTime = configuration["JwtSettings:ExpireTime"];


        }
    }

5.去新增一個JwtTokenHelper類

  public class JwtTokenHelper
    {
        public static JwtSecurityTokenHandler _jwt = new JwtSecurityTokenHandler();

        /// <summary>
        /// 頒發JWT字符串
        /// </summary>
        /// <param name="tokenModel"></param>
        /// <returns></returns>
        public static string IssueJwt(TokenModel tokenModel)
        {
            var encodedJwt = "";
            try
            {
                var claims = new Claim[]
                {
                    new Claim("userId", tokenModel.userId.ToString()),
                    new Claim("userCode", tokenModel.userCode),
                    new Claim("phone", tokenModel.phone),
                    new Claim("userName", tokenModel.userName),
                    new Claim("role", tokenModel.role),
                    new Claim("tokenType", tokenModel.tokenType.ToString())
                };

                DateTime expTime = DateTime.Now.AddSeconds(Convert.ToDouble(AppSettingsInit.JwtSettings.ExpireTime));
                //秘鑰
                var key = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(AppSettingsInit.JwtSettings.SecretKey));
                var creds = new SigningCredentials(key, SecurityAlgorithms.HmacSha256);

                var jwt = new JwtSecurityToken(
                    issuer: AppSettingsInit.JwtSettings.Issuer,
                    audience: AppSettingsInit.JwtSettings.Audience,
                    claims: claims,
                    expires: expTime,//過期時間
                    signingCredentials: creds);

                encodedJwt = _jwt.WriteToken(jwt);
            }
            catch (Exception ex)
            {

            }
            if (encodedJwt != "")
                encodedJwt = $"{JwtBearerDefaults.AuthenticationScheme} {encodedJwt}";
            return encodedJwt;
        }

        /// <summary>
        /// 解析jwt字符串
        /// </summary>
        /// <param name="jwtStr"></param>
        /// <returns></returns>
        public static TokenModel SerializeJWT(string jwtStr)
        {
            var tm = new TokenModel();
            JwtSecurityToken jwtToken = _jwt.ReadJwtToken(jwtStr);

            try
            {
                var JwtList = jwtToken.Payload;
                tm.userCode = JwtList["userCode"]?.ToString();
                tm.userId = Convert.ToInt64(JwtList["userId"]);
                tm.userCode = JwtList["userCode"]?.ToString();
                tm.phone = JwtList["phone"]?.ToString();
                tm.userName = JwtList["userName"]?.ToString();
                tm.role = JwtList["role"]?.ToString();
            }
            catch (Exception e)
            {
                // ignored
            }
            return tm;
        }
      

    }
JwtTokenHelper

6.在startup.cs中的ConfigureServices注入依賴

  public void ConfigureServices(IServiceCollection services)
        { 

            #region 配置登錄授權
            services.AddAuthentication(options =>
            {
                options.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;
                options.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme;

            }).AddJwtBearer(JwtBearerDefaults.AuthenticationScheme,
            (jwtBearerOptions) =>
            {
                jwtBearerOptions.TokenValidationParameters = new TokenValidationParameters
                {
                    //需要跟生成Token的信息保持一致
                    ValidateIssuerSigningKey = true,//驗證全局秘匙||默認True
                    IssuerSigningKey = new SymmetricSecurityKey(System.Text.Encoding.UTF8.GetBytes(AppSettingsInit.JwtSettings.SecretKey)),
                    ValidateIssuer = true,//驗證發布者||默認True
                    ValidIssuer = AppSettingsInit.JwtSettings.Issuer,
                    ValidateAudience = true,//驗證訪問者||默認True
                    ValidAudience = AppSettingsInit.JwtSettings.Audience,
                    ValidateLifetime = true,//驗證生命周期||默認True
                    ClockSkew = TimeSpan.Zero

                };
            });

            #endregion

           
            services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_1);
            

            #region 配置Swagger
            services.AddSwaggerGen(c =>
            {
                #region 頂部基礎信息

                c.SwaggerDoc("v1", new Info
                {
                    Version = "v1.1.0",
                    Title = "WebAPI",
                    Description = "API幫助文檔",
                    TermsOfService = "None",
                    Contact = new Swashbuckle.AspNetCore.Swagger.Contact { Name = "NinaMua", Email = "791016081@qq.com", Url = "http://www.cnblogs.com/NinaMua" }
                });
                #endregion

                #region 權限驗證信息

                //添加一個必須的全局安全信息,和AddSecurityDefinition方法指定的方案名稱要一致
                var security = new Dictionary<string, IEnumerable<string>> { { "Bearer", new string[] { } } };
                c.AddSecurityRequirement(security);

                c.AddSecurityDefinition("Bearer", new ApiKeyScheme
                {
                    Description = "格式|Bearer {token}",
                    Name = "Authorization",//jwt默認的參數名稱
                    In = "header",//jwt默認在請求頭中存放Authorization信息
                    Type = "apiKey"
                });

                #endregion

                #region 添加讀取注釋服務
                //添加對控制器的標簽(描述)通過對SwaggerDocTag添加備注
                //c.DocumentFilter<SwaggerDocTag>();
                var basePath = AppDomain.CurrentDomain.BaseDirectory;

                var apiXmlPath = Path.Combine(basePath, "TestApi.xml");
                if (System.IO.File.Exists(apiXmlPath))
                    c.IncludeXmlComments(apiXmlPath, true);//控制器層注釋(true表示顯示控制器注釋)

                var entityXmlPath = Path.Combine(basePath, "TestEntity.xml");
                if (System.IO.File.Exists(entityXmlPath))
                c.IncludeXmlComments(entityXmlPath);//實體類注釋
                #endregion

            });
            #endregion

        }
ConfigureServices

7.在startup.cs中的Configure注入中間件

  // This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
        public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory)
        {
            if (env.IsDevelopment())
            {
                app.UseDeveloperExceptionPage();
            }
            else
            {
                app.UseHsts();
            }

            app.UseHttpsRedirection();
            app.UseAuthentication();//配置授權

            loggerFactory.AddNLog();//添加NLog
            env.ConfigureNLog("nlog.config");//讀取Nlog配置文件

            #region Swagger
            app.UseSwagger();
            app.UseSwaggerUI(c =>
            {
                c.SwaggerEndpoint("/swagger/v1/swagger.json", "ApiHelp V1");
            });
            #endregion


            app.UseMvc();
        }
Configure

8.在api接口上加上權限認證[Authorize]

    [Route("api/")]
    public class LoginController : BaseApiController
    {
        
        public ILogger<LoginController> logger;
        /// <param name="_logger">日志</param>
        public LoginController(ILogger<LoginController> _logger)
        {
            logger = _logger;
        }

        /// <summary>
        /// 登錄
        /// </summary>
        /// <returns></returns>
        [Route("Login")]
        [HttpGet]
        public ResponseMessage Login()
        {
            ///用戶是否存在///
            TokenModel temp = new TokenModel();
            temp.userName = "系統管理員";
            temp.userCode = "system";
            temp.role = "Admin";
            temp.phone = "";
            temp.icon = "";
            var result = JwtTokenHelper.IssueJwt(temp);
            if (result != "")
                return Success(result);
            else
                return CustomizeResponse(100, "登錄失敗");
        }

        /// <summary>
        /// 退出
        /// </summary>
        /// <returns></returns>
        [HttpGet]
        [Route("SignOut")]
        [Authorize]
        public string Exit()
        {
            return "1111";
        }


    }
View Code

 9.測試

在沒有token的請求中~請求接口401

 

 拿到token后放在全局之中


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM