jwt php签名验证不通过_NET core webApi 使用JWT验证签名

一、为什么使用JWT

1.跨语言使用。

2.服务器端无需再保存任何东西,只需要客户端保存token就可以。

3.实现简单。

4.统一认证方式,如果是移动端也要验证的话,jwt也支持就无需修改,否则客户端 服务器一套,移动端 服务器又是一套

当然缺陷也是很明显,就是退出登录后,已发放的token无法销毁,可以继续访问。就是令牌给你了,如果别人盗取了你的令牌,我也是认的,我只认令牌不认人。也可以设置令牌有效期,假如设置过期有效时间为10分钟,就算你拿到了令牌想用也已经过期了,但是这就要求客户端每次想要做什么,先去申请令牌,然后再去操作,这就很麻烦。内部系统的话是可以用这种模式的,如果对外的不建议使用。对外的可以使用传统的签名认证方法。

二、在.net core webApi 搭建jwt并且使用

第一步:首先要在程序中读取appSettings配置文件信息

创建一个AppSettings.cs类,存放读取配置信息的函数 代码如下,使用Nuget 安装Microsoft.Extensions.Configuration和Microsoft.Extensions.Configuration.Json,Microsoft.Extensions.Configuration.Binder

using Microsoft.Extensions.Configuration;using Microsoft.Extensions.Configuration.Json;using System;using System.Collections.Generic;using System.Linq;namespace WebApi.Core.Common{    public class AppSettings    {        static IConfiguration Configuration { get; set; }        static string contentPath { get; set; }        public AppSettings(string contentPath)        {            string Path = "appsettings.json";            //如果你把配置文件 是 根据环境变量来分开了,可以这样写            //Path = $"appsettings.{Environment.GetEnvironmentVariable("ASPNETCORE_ENVIRONMENT")}.json";            Configuration = new ConfigurationBuilder()               .SetBasePath(contentPath)               .Add(new JsonConfigurationSource { Path = Path, Optional = false, ReloadOnChange = true })//这样的话,可以直接读目录里的json文件,而不是 bin 文件夹下的,所以不用修改复制属性               .Build();        }        public AppSettings(IConfiguration configuration)        {            Configuration = configuration;        }        ///         /// 封装要操作的字符        ///         /// 节点配置        ///         public static string app(params string[] sections)        {            try            {                if (sections.Any())                {                    return Configuration[string.Join(":", sections)];                }            }            catch (Exception)            {            }            return "";        }        ///         /// 递归获取配置信息数组        ///         ///         ///         ///         public static List app(params string[] sections)        {            List list = new List();            Configuration.Bind(string.Join(":", sections), list);            return list;        }    }}

找到webApi项目,打开Startup类,在ConfigureService函数 注册AppSettings

f12c8e9a3e37b42e90da74059bd9defc.png

编辑appsettings.json,新增红色框子的内容。

0fe5c617744178260441e049cc7025c7.png

获取调试一下

            //注册appsettings读取类            services.AddSingleton(new Appsettings(Configuration));            var text = Appsettings.app(new string[] { "AppSettings", "ConnectionStringSql" });            Console.WriteLine($"ConnectionString:{text}");            Console.ReadLine();    

运行后的结果

cab9947c05a663b9b2ed0e0d54480fba.png

接下来,我们开始正式的在项目中,注册和使用JWT,首先配置一下jwt需要的参数,在appsettings.json中,SecretKey必须大于16个,是大于,不是大于等于

fef0eea3a4a1d4a7d86614191249090d.png

在Api项目中 添加Nuget 包 IdentityModel,Microsoft.AspNetCore.Authentication.JwtBearer,Microsoft.AspNetCore.Authorization

359cf0e7670b2c1f362205e4eb1fd6a5.png

在model项目中添加一个tokenModel

using System;using System.Collections.Generic;using System.Text;namespace WebApi.Core.Model{    ///     /// 令牌    ///     public class TokenModel    {        ///         /// Id        ///         public string Uid { get; set; }        ///         /// 角色        ///         public string Role { get; set; }    }}

在Api项目中新建一个文件夹 Authorization,新建一个JwtHelper 里面有生成token 和解析token 两个方法

using System.Linq;using System.Security.Claims;using System.Text;using System.Threading.Tasks;using WebApi.Core.Common;using WebApi.Core.Model;namespace WebApi.Core.Api.Authorization{    public class JwtHelper    {        ///         /// 获取token信息        ///         ///         ///         public static string issueJwt(TokenModel tokenModel)        {            //获取Appsetting配置信息            string iss = AppSettings.app(new string[] { "AppSettings", "JwtSetting", "Issuer" });            string aud = AppSettings.app(new string[] { "AppSettings", "JwtSetting", "Audience" });            string secret = AppSettings.app(new string[] { "AppSettings", "JwtSetting", "SecretKey" });            var claims = new List                {                 /*                 * 特别重要:                   1、这里将用户的部分信息,比如 uid 存到了Claim 中,如果你想知道如何在其他地方将这个 uid从 Token 中取出来,              请看下边的SerializeJwt() 方法,或者在整个解决方案,搜索这个方法,看哪里使用了!                   2、你也可以研究下 HttpContext.User.Claims ,具体的你可以看看 Policys/PermissionHandler.cs 类中是如何使用的。                 */          //nbf 生效时间 、Jti 编号、iat 签发时间、aud 受众、exp 过期时间                new Claim(JwtRegisteredClaimNames.Jti, tokenModel.Uid.ToString()),                new Claim(JwtRegisteredClaimNames.Iat, $"{new DateTimeOffset(DateTime.Now).ToUnixTimeSeconds()}"),                new Claim(JwtRegisteredClaimNames.Nbf,$"{new DateTimeOffset(DateTime.Now).ToUnixTimeSeconds()}") ,                //这个就是过期时间,目前是过期1000秒,可自定义,注意JWT有自己的缓冲过期时间                new Claim (JwtRegisteredClaimNames.Exp,$"{new DateTimeOffset(DateTime.Now.AddSeconds(1000)).ToUnixTimeSeconds()}"),                new Claim(ClaimTypes.Expiration, DateTime.Now.AddSeconds(1000).ToString()),                new Claim(JwtRegisteredClaimNames.Iss,iss),                new Claim(JwtRegisteredClaimNames.Aud,aud),               };            // 可以将一个用户的多个角色全部赋予;            claims.AddRange(tokenModel.Role.Split(',').Select(s => new Claim(ClaimTypes.Role, s)));            //秘钥 (SymmetricSecurityKey 对安全性的要求,密钥的长度太短会报出异常)            var key = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(secret));            var creds = new SigningCredentials(key, SecurityAlgorithms.HmacSha256);            var jwt = new JwtSecurityToken(                issuer: iss,                claims: claims,                signingCredentials: creds);            var jwtHandler = new JwtSecurityTokenHandler();            var encodedJwt = jwtHandler.WriteToken(jwt);            return encodedJwt;        }        ///         /// 解析        ///         ///         ///         public static TokenModel SerializeJwt(string jwtStr)        {            var jwtHandler = new JwtSecurityTokenHandler();            JwtSecurityToken jwtToken = jwtHandler.ReadJwtToken(jwtStr);            object role;            try            {                jwtToken.Payload.TryGetValue(ClaimTypes.Role, out role);            }            catch (Exception e)            {                Console.WriteLine(e);                throw;            }            var tm = new TokenModel            {                Uid = jwtToken.Id.ToString(),                Role = role != null ? role.ToString() : "",            };            return tm;        }    }}

在UserController 新建一个login接口,获取token

        ///         /// 登录验证并且获取token        ///         ///         ///         [HttpPost]        public IActionResult LoginValidate(LoginModel loginModel)        {            string jwtStr = string.Empty;            bool suc = false;            if (loginModel != null)            {                //加登录验证                if (loginModel.UserName == "admin" && loginModel.PassWord == "123456")                {                    TokenModel tokenModel = new TokenModel { Uid = loginModel.UserName, Role = loginModel.Role };                    jwtStr = JwtHelper.issueJwt(tokenModel);                    suc = true;                }            }            return Ok(new {                 success=suc,                token = jwtStr            });        }

按F5启动,可以看到token已经生成,客户端也已经获取到。

fa7d8a84bd3d645d52260d706d180033.png

获取到了token我们怎么使用呢? 下一步 我们要在Swagger中开启 JWT服务,先安装包 Swashbuckle.AspNetCore.Filters

然后找到SwaggerSetUp.cs的AddSwaggerSetUp方法中增加以下代码

 public static void AddSwaggerSetup(this IServiceCollection services)        {            if (services == null) throw new ArgumentNullException(nameof(services));            var ApiName = "Webapi.Core";            services.AddSwaggerGen(c =>            {                c.SwaggerDoc("V1", new OpenApiInfo                {                    // {ApiName} 定义成全局变量,方便修改                    Version = "V1",                    Title = $"{ApiName} 接口文档——Netcore 3.0",                    Description = $"{ApiName} HTTP API V1",                });                c.OrderActionsBy(o => o.RelativePath);                // 获取xml注释文件的目录                var xmlPath = Path.Combine(AppContext.BaseDirectory, "WebApi.Core.Api.xml");                c.IncludeXmlComments(xmlPath, true);//默认的第二个参数是false,这个是controller的注释,记得修改                // 获取xml注释文件的目录                var xmlPathModel = Path.Combine(AppContext.BaseDirectory, "WebApi.Core.Model.xml");                c.IncludeXmlComments(xmlPathModel, true);//默认的第二个参数是false,这个是controller的注释,记得修改                //在 header中添加token,传递到后台                c.OperationFilter();                #region Token绑定到configureServices                c.AddSecurityDefinition("oauth2", new OpenApiSecurityScheme                {                    Description = "JWT授权(数据将在请求头中进行传输) 直接在下框中输入Bearer {token}(注意两者之间是一个空格)"",                    Name = "Authorization",//jwt默认的参数名称                    In = ParameterLocation.Header,//jwt默认存放Authorization信息的位置(请求头中)                    Type = SecuritySchemeType.ApiKey                });                #endregion            });        }

按F5运行 可以看到 token入口了,按要求的格式在 value中输入 token 以后的请求head 就会一直加入token了。

552ef49d01d825916ed688eb622c9dbc.png
530a28e903987df91e20014125d46acb.png
cec8071a5c54a028175017438a405a57.png

下面该授权token 的认证了,在SetupService 文件夹下 新建一个AuthJwtSetup.cs 类 如下

using Microsoft.AspNetCore.Authentication.JwtBearer;using Microsoft.Extensions.DependencyInjection;using Microsoft.IdentityModel.Tokens;using System;using System.Collections.Generic;using System.Linq;using System.Text;using System.Threading.Tasks;using WebApi.Core.Common;namespace WebApi.Core.Api.SetUpService{    public static class AuthJwtSetup    {        public static void AddAuthorizationJwtSetUp(this IServiceCollection services)        {            if (services == null) throw new ArgumentNullException(nameof(services));            //读取配置文件            var symmetricKeyAsBase64 = AppSettings.app(new string[] { "AppSettings", "JwtSetting", "SecretKey" });            var keyByteArray = Encoding.ASCII.GetBytes(symmetricKeyAsBase64);            var signingKey = new SymmetricSecurityKey(keyByteArray);            var Issuer = AppSettings.app(new string[] { "AppSettings", "JwtSetting", "Issuer" });            var Audience = AppSettings.app(new string[] { "AppSettings", "JwtSetting", "Audience" });            // 令牌验证参数            var tokenValidationParameters = new TokenValidationParameters            {                ValidateIssuerSigningKey = true,                IssuerSigningKey = signingKey,                ValidateIssuer = true,                ValidIssuer = Issuer,//发行人                ValidateAudience = true,                ValidAudience = Audience,//订阅人                ValidateLifetime = true,                ClockSkew = TimeSpan.FromSeconds(30), //token过期后 还可以继续多访问30秒                RequireExpirationTime = true,            };            //2.1【认证】、core自带官方JWT认证            // 开启Bearer认证            services.AddAuthentication("Bearer")             // 添加JwtBearer服务             .AddJwtBearer(o =>             {                 o.TokenValidationParameters = tokenValidationParameters;                 o.Events = new JwtBearerEvents                 {                     OnAuthenticationFailed = context =>                     {                         // 如果过期,则把添加到,返回头信息中                         if (context.Exception.GetType() == typeof(SecurityTokenExpiredException))                         {                             context.Response.Headers.Add("Token-Expired", "true");                         }                         return Task.CompletedTask;                     }                 };             });        }    }}

startup.cs的ConfigureServices 方法添加 服务注入

//jwt授权验证services.AddAuthorizationSetup();

Configure方法添加 下面的代码

fd8bd22929aa9a20f54f3c986e0dbad5.png

接口授权策略验证,在UserController里面添加一个方法

6a11caa5f099bf14ea80dec0f5097c20.png

按F5启动调试,先获取Admin角色权限的token,添加token到header中,然后请求 验证角色权限那个接口,验证成功。

399bd61ad5b17f114db5e3f7292df96f.png
d9122286188b9175bef51e4a4269a9ad.png
a22fdfff73281628631482cda1706835.png

如果获取的token 不是Admin 角色权限我们再来试一下,看看是什么结果,结果就是没有访问权限。

2b5c50122891d0d4d512e7e2b3f81cde.png
f1f3b0f7fbaa185556de487f9f6fe601.png

下面该解析Token 了,试一下,添加一个接口,步骤同上,先获取token,然后绑定token,最后调用一下解析接口,看结果我们已经解析成功了。

cca6809d9f9c3135d58f73842620df3e.png
4defc1e1c6631265383ee31b88e8bc89.png
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
在.NET Core Web API中,你可以使用JWT(JSON Web Token)来进行身份验证和授权。要获取当前登录用户,你需要在每个请求中检查JWT令牌,并将其解码以获取用户信息。以下是一些步骤: 1. 在你的.NET Core Web API应用程序中添加JWT身份验证中间件。你可以使用现有的第三方库,如Microsoft.AspNetCore.Authentication.JwtBearer,或者自己编写中间件。 2. 在身份验证成功后,从请求中获取JWT令牌。你可以从HTTP请求头中获取令牌,或者从请求正文中获取令牌。 3. 解码JWT令牌以获取用户信息。JWT令牌包含有关用户的信息,例如用户名、角色和权限。你可以使用JWT库来解码令牌并访问其内容。 以下是一些示例代码,演示如何在.NET Core Web API中获取当前用户: ```csharp // 在Startup.cs中添加JWT身份验证中间件 public void Configure(IApplicationBuilder app, IWebHostEnvironment env) { app.UseAuthentication(); // ... } // 在Controller中获取当前用户 [Authorize] [ApiController] [Route("[controller]")] public class MyController : ControllerBase { // 获取当前用户的用户名 [HttpGet] public IActionResult Get() { var username = User.Identity.Name; return Ok($"Hello, {username}!"); } } ``` 在上面的代码中,我们使用了[Authorize]属性来确保只有经过身份验证的用户才能访问MyController。然后,在Get()方法中,我们使用User.Identity.Name属性来获取当前用户的用户名。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值