.Net6 生成Token 和 刷新Token

这篇具有很好参考价值的文章主要介绍了.Net6 生成Token 和 刷新Token。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。


前言

关于Token的基础概念请自行百度,这里只是记录一下如何生成Token的流程及使用到的技术。


一、引入Nuget包

生成Token和验证Token主要使用下面这个包。

Install-Package Microsoft.AspNetCore.Authentication.JwtBearer

二、生成步骤

1.添加配置文件

在API项目的配置文件中增加关于Token的配置信息。
代码如下:

{
  "Logging": {
    "LogLevel": {
      "Default": "Information",
      "Microsoft.AspNetCore": "Warning"
    }
  },
  "AllowedHosts": "*",
  "JwtSettings": {
    "Issuer": "https://localhost:7141", //颁发者
    "Audience": "https://localhost:7141", //使用者
    "SecrentKey": "fdsfdsfdfdsfdsfsdfdfsdf", //秘钥
    "Expirces": 3600, //Token过期时间,
    "RefreshTokenExpirces": 3600 //refresh_Token过期时间
  }
}

需要注意的是SecrentKey 的值必须大于16位,不然在生成Token时会报错。

2.创建对应的实体

我们先创建一个和配置文件中相对应的实体,命名为JwtSettings。
代码如下:

namespace JwtDemo
{
    /// <summary>
    /// JWT 配置信息
    /// </summary>
    public class JwtSettings
    {
        /// <summary>
        /// 颁发者
        /// </summary>
        public string Issuer { get; set; }

        /// <summary>
        /// 使用者
        /// </summary>
        public string Audience { get; set; }

        /// <summary>
        /// 私钥
        /// </summary>
        public string SecrentKey { get; set; }

        /// <summary>
        /// Token过期时间 单位秒
        /// </summary>
        public int Expirces { get; set; }

        /// <summary>
        /// Refresh_Token过期时间 单位秒
        /// </summary>
        public int RefreshTokenExpirces { get; set; }
    }
}

创建一个用于返回Token的实体,命名为 ResponseToken

namespace JwtDemo
{
    /// <summary>
    /// Token的返回实体
    /// </summary>
    public class ResponseToken
    {

        /// <summary>
        /// JWT Token
        /// </summary>
        public string Token { get; set; }

        /// <summary>
        /// 用于刷新token的刷新令牌
        /// </summary>
        public string Refresh_Token { get; set; }
    }
}

3.Program.cs中注入服务

using JwtDemo;
using Microsoft.AspNetCore.Authentication.JwtBearer;
using Microsoft.IdentityModel.Tokens;
using Microsoft.OpenApi.Models;
using System.Text;

var builder = WebApplication.CreateBuilder(args);

// Add services to the container.

builder.Services.AddControllers();
// Learn more about configuring Swagger/OpenAPI at https://aka.ms/aspnetcore/swashbuckle
builder.Services.AddEndpointsApiExplorer();
builder.Services.AddSwaggerGen();

builder.Services.AddTransient<TokenHelper>();

builder.Services.Configure<JwtSettings>(builder.Configuration.GetSection("JwtSettings"));

builder.Services.AddSwaggerGen(options =>
{
    var scheme = new OpenApiSecurityScheme()
    {
        Description = "Authorization header.\r\n Example:'Bearer 123'",
        Reference = new OpenApiReference { Type = ReferenceType.SecurityScheme, Id = "Authorization" },
        Scheme = "oauth2",
        Name = "Authorization",
        In = ParameterLocation.Header,
        Type = SecuritySchemeType.ApiKey
    };
    options.AddSecurityDefinition("Authorization", scheme);
    var requirement = new OpenApiSecurityRequirement();
    requirement[scheme] = new List<string>();
    options.AddSecurityRequirement(requirement);
});

builder.Services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme).AddJwtBearer(opt =>
{
    var jwtSettings = builder.Configuration.GetSection("JwtSettings").Get<JwtSettings>();
    byte[] keyBytes = Encoding.UTF8.GetBytes(jwtSettings.SecrentKey);
    var secKey = new SymmetricSecurityKey(keyBytes);
    opt.TokenValidationParameters = new()
    {
        ValidateIssuer = true, //验证颁发者
        ValidIssuer = jwtSettings.Issuer,
        ValidateAudience = true,  // 验证使用者
        ValidAudience = jwtSettings.Audience,
        ValidateLifetime = true, //是否验证Token有效期,使用当前时间与Token的Claims中的NotBefore和Expires对比
        ValidateIssuerSigningKey = true, //验证秘钥
        IssuerSigningKey = secKey,
        RequireExpirationTime = true,//要求Token的Claims中必须包含Expires
        ClockSkew = TimeSpan.Zero, //允许服务器时间偏移量300秒,即我们配置的过期时间加上这个允许偏移的时间值,才是真正过期的时间(过期时间 + 偏移值)你也可以设置为0,ClockSkew = TimeSpan.Zero
    };

});

var app = builder.Build();

// Configure the HTTP request pipeline.
if (app.Environment.IsDevelopment())
{
    app.UseSwagger();
    app.UseSwaggerUI();
}

app.UseHttpsRedirection();

app.UseAuthentication();

app.UseAuthorization();

app.MapControllers();

app.Run();

builder.Services.AddSwaggerGen(); 是用来在Swagger中添加一个填写Token的按钮

builder.Services.AddAuthentication();是用来配置关于验证Token的一些配置。

app.UseAuthentication(); 添加身份认证,一定要在app.UseAuthorization()的上面。


4.Token的生成和刷新

在帮助类中并没有将Token和refreshToken 存在缓存中,大家可根据自己的业务自行添加对应的逻辑。

using Microsoft.AspNetCore.Authentication.JwtBearer;
using Microsoft.Extensions.Caching.Distributed;
using Microsoft.Extensions.Options;
using Microsoft.IdentityModel.Tokens;
using System.IdentityModel.Tokens.Jwt;
using System.Security.Claims;
using System.Security.Cryptography;
using System.Text;

namespace JwtDemo
{
    /// <summary>
    /// Token的帮助类
    /// </summary>
    public class TokenHelper
    {
        private readonly IOptionsSnapshot<JwtSettings> _jwtSettings;

        public TokenHelper(IOptionsSnapshot<JwtSettings> jwtSettings)
        {
            _jwtSettings = jwtSettings;
        }

        /// <summary>
        /// 颁发Token
        /// </summary>
        /// <returns></returns>
        public ResponseToken CreateToken()
        {
            List<Claim> claims = new List<Claim>()
            {
                new Claim(ClaimTypes.NameIdentifier, "1"),
                new Claim(ClaimTypes.Name, "jjm")
            };

            string key = _jwtSettings.Value.SecrentKey;

            DateTime now = DateTime.Now;

            var expores = now.AddSeconds(_jwtSettings.Value.Expirces);

            byte[] secBytes = Encoding.UTF8.GetBytes(key);
            var secKey = new SymmetricSecurityKey(secBytes);
            var credentials = new SigningCredentials(secKey, SecurityAlgorithms.HmacSha256Signature);

            var tokenDescriptor = new JwtSecurityToken(
                issuer: _jwtSettings.Value.Issuer,
                audience: _jwtSettings.Value.Audience,
                claims: claims,
                notBefore: now,
                expires: expores,
                signingCredentials: credentials);


            string token = new JwtSecurityTokenHandler().WriteToken(tokenDescriptor);
            string refreshToken = CreateRefreshToken();

            //需要将两个Token 都放在缓存中

            return new ResponseToken() { Token = token, Refresh_Token = refreshToken };
        }

        /// <summary>
        /// 生成refresh_Token
        /// </summary>
        /// <returns></returns>
        public string CreateRefreshToken()
        {
            var refresh = new byte[32];
            using (var number = RandomNumberGenerator.Create())
            {
                number.GetBytes(refresh);
                return Convert.ToBase64String(refresh);
            }

            //将refresh_Token存在缓存中
        }

        public ResponseToken Refresh(string Token, string refresh_Token)
        {
            string key = _jwtSettings.Value.SecrentKey;

            byte[] secBytes = Encoding.UTF8.GetBytes(key);
            var secKey = new SymmetricSecurityKey(secBytes);

            var tokenHandler = new JwtSecurityTokenHandler();
            SecurityToken validatedToken;

            // 根据过期Token获取一个SecurityToken
            var principal = tokenHandler.ValidateToken(Token, new TokenValidationParameters()
            {
                ValidateIssuerSigningKey = true,
                IssuerSigningKey = secKey,
                ValidateIssuer = true,
                ValidIssuer = _jwtSettings.Value.Issuer,
                ValidateAudience = true,
                ValidAudience = _jwtSettings.Value.Audience,
                ValidateLifetime = false
            }, out validatedToken);

            var jwtToken = validatedToken as JwtSecurityToken;

            if (jwtToken == null || !jwtToken.Header.Alg.Equals(SecurityAlgorithms.HmacSha256Signature, StringComparison.InvariantCultureIgnoreCase))
            {
                throw new SecurityTokenException("Token不合法");
            }

            //判断refresh_Token是否此用户生成的

            //生成新Token
            List<Claim> claims = new List<Claim>()
            {
                new Claim(ClaimTypes.NameIdentifier, "1"),
                new Claim(ClaimTypes.Name, "jjm")
            };

            var jwtSecurityToken = new JwtSecurityToken(
                claims: claims,
                notBefore: DateTime.Now,
                expires: DateTime.Now.AddSeconds(_jwtSettings.Value.Expirces),
                issuer: _jwtSettings.Value.Issuer,
                audience: _jwtSettings.Value.Audience,
                signingCredentials: new SigningCredentials(secKey, SecurityAlgorithms.HmacSha256Signature)
                );

            var token = new JwtSecurityTokenHandler().WriteToken(jwtSecurityToken);
            var refreshToken = CreateRefreshToken();

            //将缓存中原来的Token和refresh_Token 删除掉,并且保存新生成的Token

            return new ResponseToken() { Token = token, Refresh_Token = refreshToken };
        }
    }
}


5.创建Controller

[Authorize]: 将则会个特性放在控制器头部的话,整个控制器的所有方法都会需要验证。
[AllowAnonymous]:如果某个方法不需要进行Token的验证,则可以添加这个特性

using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;

namespace JwtDemo.Controllers
{
    [ApiController]
    [Route("[controller]/[action]")]
    public class WeatherForecastController : ControllerBase
    {
        private TokenHelper _tokenHelper;
        private readonly ILogger<WeatherForecastController> _logger;

        public WeatherForecastController(ILogger<WeatherForecastController> logger, TokenHelper tokenHelper)
        {
            _logger = logger;
            _tokenHelper = tokenHelper;
        }

        /// <summary>
        /// 登录
        /// </summary>
        /// <param name="user">用户名</param>
        /// <param name="pwd">密码</param>
        /// <returns></returns>
        [HttpPost]
        public IActionResult Login(string user, string pwd)
        {
            if (user == "jjm" && pwd == "123")
            {
                return Ok(_tokenHelper.CreateToken());
            }
            else
            {
                return BadRequest();
            }
        }

        [HttpGet]
        [Authorize]
        public IActionResult Demo1()
        {
            return Ok("1232131");
        }

        [HttpGet]
        [AllowAnonymous]
        public IActionResult Result(string token, string refresh_token)
        {
            return Ok(_tokenHelper.Refresh(token, refresh_token));
        }
    }
}

6.测试

  1. 输入后台写死的用户名和密码获取Token

.Net6 生成Token 和 刷新Token

  1. 请求头增加Authorization参数,值为:Bearer +Token。(Bearer和Token 中间有空格)
    .Net6 生成Token 和 刷新Token

  2. 通过refresh_token刷新Token
    .Net6 生成Token 和 刷新Token

总结

以上就是生成、验证、刷新Token 的全部代码,当然这个比较简单,并没有加入相关的验证逻辑,大家可自行添加。文章来源地址https://www.toymoban.com/news/detail-461047.html

到了这里,关于.Net6 生成Token 和 刷新Token的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • .net基础概念

    .NET Framework开发平台包含公共语言运行库(CLR)和基类库(BCL),前者负载管理代码的执行,后者提供了丰富的类库来构建应用程序。.NET Framework仅支持Windows平台 由于.NET Framework支支持windows环境,因此社区开发了Mono,是可以跨平台运行的,但是其远远落后于.NETFramework的官方实现

    2024年02月10日
    浏览(27)
  • 微信小程序自动刷新token,无感刷新token

            小程序登录开发通常是调用wx.login获取code,然后发送到后台,后台请求微信拿到用户openId,然后根据openId查询用户,有就走登录流程然后返回token,没有则创建用户之后走登录流程然后返回token,也就是都需要返回一个有时效性的token给小程序端,来保持登录状态,

    2024年02月12日
    浏览(39)
  • 前端刷新token,判断token是否过期,若没有过期则刷新token,过期则退出登录

    vue+axios 假设后端设置的token过期时间为10分钟。那么登录以后,过十分钟后token就会过期,这时再去操作系统,所有的请求都不能用,都会报token过期,需要重新登录才能继续操作系统。这样的方式显然是不合理的,为了解决这个问题,就需要在一段时间内刷新token。 在请求拦

    2024年02月12日
    浏览(62)
  • IdentityServer4 获取Token及刷新Token

    一、获取Token 使用PostMan,调用接口:http://192.168.31.132:7000/connect/token     二、刷新Token  使用PostMan,调用接口:http://192.168.31.132:7000/connect/token  

    2024年02月17日
    浏览(47)
  • 关于 K8s 的一些基础概念整理

    Kubernetes,将中间八个字母用数字 8 替换掉简称 k8s,是一个开源的 容器集群管理系统 ,由谷歌开发并维护。它为 跨主机的容器化应用 提供 资源调度、服务发现、高可用管理 和 弹性伸缩 等功能。 下面简单列一下 k8s 的几个特性: 自动化部署: Kubernetes 可以根据应用程序计

    2024年02月04日
    浏览(44)
  • 无感刷新:Vue前端实现Token的无缝刷新机制

    在现代Web应用程序中,用户身份验证和授权通常使用令牌(Token)机制来实现。然而,由于Token的过期时间限制,用户在长时间使用应用程序时可能需要重新登录。为了提供更好的用户体验,我们可以通过实现Token的无感刷新机制来避免用户在使用过程中的中断。本文将探讨如

    2024年02月10日
    浏览(41)
  • 前端刷新token,判断token是否过期(jwt鉴权)

    4.1 什么是 JWT JWT 是 Auth0 提出的通过 对 JSON 进行加密签名来实现授权验证的方案; 就是登录成功后将相关用户信息组成 JSON 对象,然后对这个对象进行某种方式的加密,返回给客户端; 客户端在下次请求时带上这个 Token; 服务端再收到请求时校验 token 合法性,其实也就是在

    2024年02月03日
    浏览(62)
  • .Net6下使用Ado.Net

    Ado.Net,是微软提供的在.Net平台下操作数据库(本文实例记录MySQL、SQLSever数据的基本操作)、XML文件和应用程序数据的一个工具。是应用程序和数据库之间的数据桥梁。它拥有一组丰富的类、方法和接口,有效地处理数据库中的数据。(上层的ORM框架《EFCore、Dapper等》都是对它

    2024年02月05日
    浏览(52)
  • 关于.Net 6.0 在Linux ,Docker容器中,不安装任何依赖就生成图形验证码!!!!!!!!!!!

    在.Net Framework时代,我们生成验证码大多都是用System.Drawing。 在.Net 6中使用也是没有问题的。 但是,System.Drawing却依赖于Windows GDI+。 为了实现跨平台,我陷入了沉思!!   微软推荐使用SkiaSharp 进行替代,所以就开始了,踩坑之旅 首先,安装SkiaSharp  编写好图形生成代码。    

    2024年02月08日
    浏览(75)
  • 无感刷新 token

    前景提要: ts 简易封装 axios,统一 API 实现在 config 中配置开关拦截器 axios 实现请求 loading 效果 无感刷新 token 一般指的是使用 refresh token 无感刷新 access token。 设置全局请求拦截器,从 localstorage 或其他地方获取 token 放在请求头中携带。在响应拦截器中,判断响应结果中是否

    2024年02月06日
    浏览(43)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包