返回顶部
首页 > 资讯 > 后端开发 > 其他教程 >C# 如何实现Token
  • 159
分享到

C# 如何实现Token

2024-04-02 19:04:59 159人浏览 独家记忆
摘要

目录什么是Jwt基于session认证所显露的问题基于token的鉴权机制JWT的构成C# mvc实现token什么是JWT JWT:JSON WEB token (JWT), 是

什么是JWT

JWT:JSON WEB token (JWT), 是为了在网络应用环境间传递声明而执行的一种基于jsON的开放标准((RFC 7519).该token被设计为紧凑且安全的,特别适用于分布式站点的单点登录(SSO)场景。JWT的声明一般被用来在身份提供者和服务提供者间传递被认证的用户身份信息,以便于从资源服务器获取资源,也可以增加一些额外的其它业务逻辑所必须的声明信息,该token也可直接被用于认证,也可被加密。

传统的session认证

我们知道,Http协议本身是一种无状态的协议,而这就意味着如果用户向我们的应用提供了用户名和密码来进行用户认证,那么下一次请求时,用户还要再一次进行用户认证才行,因为根据http协议,我们并不能知道是哪个用户发出的请求,所以为了让我们的应用能识别是哪个用户发出的请求,我们只能在服务器存储一份用户登录的信息,这份登录信息会在响应时传递给浏览器,告诉其保存为cookie,以便下次请求时发送给我们的应用,这样我们的应用就能识别请求来自哪个用户了,这就是传统的基于session认证。

但是这种基于session的认证使应用本身很难得到扩展,随着不同客户端用户的增加,独立的服务器已无法承载更多的用户,而这时候基于session认证应用的问题就会暴露出来.

基于session认证所显露的问题

Session: 每个用户经过我们的应用认证之后,我们的应用都要在服务端做一次记录,以方便用户下次请求的鉴别,通常而言session都是保存在内存中,而随着认证用户的增多,服务端的开销会明显增大。

扩展性: 用户认证之后,服务端做认证记录,如果认证的记录被保存在内存中的话,这意味着用户下次请求还必须要请求在这台服务器上,这样才能拿到授权的资源,这样在分布式的应用上,相应的限制了负载均衡器的能力。这也意味着限制了应用的扩展能力。

CSRF: 因为是基于cookie来进行用户识别的, cookie如果被截获,用户就会很容易受到跨站请求伪造的攻击。

基于token的鉴权机制

基于token的鉴权机制类似于http协议也是无状态的,它不需要在服务端去保留用户的认证信息或者会话信息。这就意味着基于token认证机制的应用不需要去考虑用户在哪一台服务器登录了,这就为应用的扩展提供了便利。

流程上是这样的:

  • 用户使用用户名密码来请求服务器
  • 服务器进行验证用户的信息
  • 服务器通过验证发送给用户一个token
  • 客户端存储token,并在每次请求时附送上这个token值
  • 服务端验证token值,并返回数据

这个token必须要在每次请求时传递给服务端,它应该保存在请求头里, 另外,服务端要支持CORS(跨来源资源共享)策略,一般我们在服务端这么做就可以了Access-Control-Allow-Origin: *。

那么我们现在回到JWT的主题上。

JWT的构成

第一部分我们称它为头部(header),第二部分我们称其为载荷(payload, 类似于飞机上承载的物品),第三部分是签证(signature).

C# MVC实现token

1.在NuGet中引用JWT

2.创建一个实体 UserInfo类


using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;

namespace WebApplication1.model
{
 public class UserInfo
 {
  public string UserName { get; set; }

  public string Pwd { get; set; }
 }
}

3.创建JWT帮助类


using JWT;
using JWT.AlGorithms;
using JWT.Serializers;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;

namespace WebApplication1.model
{
 public class JwtHelp
 {
  //私钥 web.config中配置
  //"GQDstcKsx0NHjPOuXOYg5MbeJ1XT0uFiwDVvVBrk";
  private static string secret = "GQDstcKsx0NHjPOuXOYg5MbeJ1XT0uFiwDVvVBrk";
  //ConfigurationManager.AppSettings["Secret"].ToString();

  /// <summary>
  /// 生成JwtToken
  /// </summary>
  /// <param name="payload">不敏感的用户数据</param>
  /// <returns></returns>
  public static string SetJwtEncode(Dictionary<string, object> payload)
  {

   //格式如下
   //var payload = new Dictionary<string, object>
   //{
   // { "username","admin" },
   // { "pwd", "claim2-value" }
   //};

   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>
  /// 根据jwtToken 获取实体
  /// </summary>
  /// <param name="token">jwtToken</param>
  /// <returns></returns>
  public static UserInfo GetJwtDecode(string token)
  {
   IJsonSerializer serializer = new JsonNetSerializer();
   IDateTimeProvider provider = new UtcDateTimeProvider();
   IJwtValidator validator = new JwtValidator(serializer, provider);
   IBase64UrlEncoder urlEncoder = new JwtBase64UrlEncoder();
   var algorithm = new HMACSHA256Algorithm();
   IJwtDecoder decoder = new JwtDecoder(serializer, validator, urlEncoder, algorithm);
   var userInfo = decoder.DecodeToObject<UserInfo>(token, secret, verify: true);//token为之前生成的字符串
   return userInfo;
  }
 }
}

4.创建一个编码类DESCryption


using System;
using System.Text;
using System.Security.Cryptography;
using System.IO;
using System.Configuration;

namespace JWT.MvcDemo.Help
{

 public class DESCryption
 {

  /// <summary>
  /// //注意了,是8个字符,64位
  /// </summary>
  private static string PrivateRsa = ConfigurationManager.AppSettings["PrivateRsa"];

  /// <summary>
  /// //注意了,是8个字符,64位
  /// </summary>
  private static string PublicRsa = ConfigurationManager.AppSettings["PublicRsa"];

  /// <summary>
  /// 加密
  /// </summary>
  /// <param name="data"></param>
  /// <returns></returns>
  public static string Encode(string data)
  {
   byte[] byKey = Encoding.ASCII.GetBytes(PrivateRsa);
   byte[] byIV = Encoding.ASCII.GetBytes(PublicRsa);

   DESCryptoServiceProvider cryptoProvider = new DESCryptoServiceProvider();
   int i = cryptoProvider.KeySize;
   MemoryStream ms = new MemoryStream();
   CryptoStream cst = new CryptoStream(ms, cryptoProvider.CreateEncryptor(byKey, byIV), CryptoStreamMode.Write);

   StreamWriter sw = new StreamWriter(cst);
   sw.Write(data);
   sw.Flush();
   cst.FlushFinalBlock();
   sw.Flush();
   return Convert.ToBase64String(ms.GetBuffer(), 0, (int)ms.Length);

  }

  /// <summary>
  /// 解密
  /// </summary>
  /// <param name="data"></param>
  /// <returns></returns>
  public static string Decode(string data)
  {
   byte[] byKey = Encoding.ASCII.GetBytes(PrivateRsa);
   byte[] byIV = Encoding.ASCII.GetBytes(PublicRsa);

   byte[] byEnc;
   try
   {
    byEnc = Convert.FromBase64String(data);
   }
   catch
   {
    return null;
   }

   DESCryptoServiceProvider cryptoProvider = new DESCryptoServiceProvider();
   MemoryStream ms = new MemoryStream(byEnc);
   CryptoStream cst = new CryptoStream(ms, cryptoProvider.CreateDecryptor(byKey, byIV), CryptoStreamMode.Read);
   StreamReader sr = new StreamReader(cst);
   return sr.ReadToEnd();
  }

 }
}

5.创建一个返回消息类


using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;

namespace JWT.MvcDemo.Models
{
 public class DataResult
 {
  /// <summary>
  /// 
  /// </summary>
  public string Token { get; set; }

  public bool Success { get; set; }

  public string Message { get; set; }

 }
}

6.创建一个控制器用于生产token


using JWT.MvcDemo.Models;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using WebApplication1.model;

namespace WebApplication1.Controllers
{
 public class JwtController : Controller
 {
  // GET: Jwt
  public ActionResult Index()
  {
   return View();
  }

  /// <summary>
  /// 创建jwtToken
  /// </summary>
  /// <param name="username"></param>
  /// <param name="pwd"></param>
  /// <returns></returns>
  public ActionResult CreateToken(string username, string pwd)
  {

   DataResult result = new DataResult();

   //假设用户名为"admin",密码为"123" 
   if (username == "admin" && pwd == "123")
   {

    var payload = new Dictionary<string, object>
    {
     { "username",username },
     { "pwd", pwd }
    };

    result.Token = JwtHelp.SetJwtEncode(payload);
    result.Success = true;
    result.Message = "成功";
   }
   else
   {
    result.Token = "";
    result.Success = false;
    result.Message = "生成token失败";
   }

   //return Json(result);
   //get请求需要修改成这样
   return Json(result,JsonRequestBehavior.AllowGet);
  }
 }
}

7.创建一个自定义过滤器


using JWT.MvcDemo.Help;
using System;
using System.Collections.Generic;
using System.Configuration;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using System.Web.Security;
using WebApplication1.model;

namespace JWT.MvcDemo.App_Start
{
 public class MyAuthorizeAttribute : AuthorizeAttribute
 {

  private readonly string TimeStamp = ConfigurationManager.AppSettings["TimeStamp"];

  /// <summary>
  /// 验证入口
  /// </summary>
  /// <param name="filterContext"></param>
  public override void OnAuthorization(AuthorizationContext filterContext)
  {
   base.OnAuthorization(filterContext);
  }

  /// <summary>
  /// 验证核心代码
  /// </summary>
  /// <param name="httpContext">fbc8ZBLd5ZbtCoGCY9NUVV4HZbPln1lb</param>
  /// <returns></returns>
  protected override bool AuthorizeCore(HttpContextBase httpContext)
  {

   //前端请求api时会将token存放在名为"auth"的请求头中
   var authHeader = httpContext.Request.Headers["auth"];
   if (authHeader == null)
    return false;

   //请求参数
   string requestTime = httpContext.Request["rtime"]; //请求时间经过DESC签名
   if (string.IsNullOrEmpty(requestTime))
    return false;

   //模拟生成rtime 时间戳,即登录的时间,加密.       //实际生产中这段代码应该在请求段。此处只为了程序验证通过
   string r= DESCryption.Encode(DateTime.Now.ToString());
   requestTime = r;


    //请求时间RSA解密后加上时间戳的时间即该请求的有效时间
    DateTime Requestdt = DateTime.Parse(DESCryption.Decode(requestTime)).AddMinutes(int.Parse(TimeStamp));
    DateTime Newdt = DateTime.Now; //服务器接收请求的当前时间

   if (Requestdt < Newdt)
   {
    return false;
   }
   else
   {
    if (authHeader != null)
    {
     //进行其他操作
     var userinfo = JwtHelp.GetJwtDecode(authHeader);
     //举个例子 生成jwtToken 存入Redis中 
     //这个地方用jwtToken当作key 获取实体val 然后看看jwtToken根据redis是否一样
     if (userinfo.UserName == "admin" && userinfo.Pwd == "123")
      return true;
    }

   }

   return false;
  }

  /// <summary>
  /// 验证失败处理
  /// </summary>
  /// <param name="filterContext"></param>
  protected override void HandleUnauthorizedRequest(AuthorizationContext filterContext)
  {
   base.HandleUnauthorizedRequest(filterContext);
   filterContext.Result = new RedirectResult("/Error");
   filterContext.HttpContext.Response.Redirect("/Home/Error");
  }


 }
}

8.在要需要过滤的控制器方法上添加标签,标签就是自定义过滤器名称。


using JWT.MvcDemo.App_Start;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;

namespace WebApplication1.Controllers
{
 public class HomeController : Controller
 {
  public ActionResult Index()
  {
   return View();
  }

  [HttpPost]
  [MyAuthorize]
  public string About()
  {
   string rtJson = "{\"code\": 0}";
   try
   {

    rtJson = "{\"code\":0,\"data\":[],\"msg\":\"Your application description page.\",\"count\":1}";
   }
   catch
   {
    rtJson = "{\"code\": 0}";
   }
   return rtJson;
  }


  public ActionResult Contact()
  {
   ViewBag.Message = "Your contact page.";

   return View();
  }
 }
}

9.测试获取token

10.客户端将token放入header中达到携带token目的。

11.需要在web.config 中添加设置值


 <add key="Secret" value="GQDstcKsx0NHjPOuXOYg5MbeJ1XT0uFiwDVvVBrk"/>
  <add key="PrivateRsa" value="GQDstcKs"/>
  <add key="PublicRsa" value="DVvVBrkx0"/>
  <add key="TimeStamp" value="2"/>

以上就是C# 如何实现Token的详细内容,更多关于C# 实现Token的资料请关注编程网其它相关文章!

--结束END--

本文标题: C# 如何实现Token

本文链接: https://lsjlt.com/news/121649.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

猜你喜欢
  • C# 如何实现Token
    目录什么是JWT基于session认证所显露的问题基于token的鉴权机制JWT的构成C# MVC实现token什么是JWT JWT:Json web token (JWT), 是...
    99+
    2024-04-02
  • vue获取token如何实现token登录
    目录vue获取token 实现token登录使用token做登录验证的思路大致如下实际步骤vue中token的处理传统的token处理VUEX的存储方法项目中的token处理方法vu...
    99+
    2024-04-02
  • SpringBoot如何实现token登录
    这篇文章主要为大家展示了“SpringBoot如何实现token登录”,内容简而易懂,条理清晰,希望能够帮助大家解决疑惑,下面让小编带领大家一起研究并学习一下“SpringBoot如何实现token登录”这篇文章吧。为什么引入token机制...
    99+
    2023-06-29
  • 如何实现无感刷新token
    目录1、需求方法一方法二方法三2、实现3、问题解决问题一:如何防止多次刷新token问题二:同时发起两个或者两个以上的请求时,其他接口怎么解决前言: 最近在做需求的时候,涉及到登录t...
    99+
    2024-04-02
  • C# 怎么实现Token的方法
    本篇内容介绍了“C# 怎么实现Token的方法”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!什么是JWTJWT:Json web token...
    99+
    2023-06-14
  • Java如何实现登录token令牌
    目录一、流程图二、Token三、分析四、运行结果一、流程图 二、Token 1、token是一种客户端认证机制,是一个经过加密的字符串,安全性强,支持跨域 2、用户第一次登录,服务...
    99+
    2024-04-02
  • Java如何实现Token登录验证
    这篇文章主要介绍“Java如何实现Token登录验证”,在日常操作中,相信很多人在Java如何实现Token登录验证问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”Java如何实现Token登录验证”的疑惑有所...
    99+
    2023-07-05
  • php如何实现响应头增加token
    这篇文章主要介绍“php如何实现响应头增加token”,在日常操作中,相信很多人在php如何实现响应头增加token问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”php如何实现响应头增加token”的疑惑有所...
    99+
    2023-07-05
  • PHP如何实现JWT的Token登录认证
    本篇内容介绍了“PHP如何实现JWT的Token登录认证”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!1、JWT简介JSON Web Tok...
    99+
    2023-06-21
  • node如何实现基于token的身份验证
    小编给大家分享一下node如何实现基于token的身份验证,相信大部分人都还不怎么了解,因此分享这篇文章给大家参考一下,希望大家阅读完这篇文章后大有收获,下面让我们一起去了解一下吧!最近研究了下基于toke...
    99+
    2024-04-02
  • springsecurity如何实现基于token的认证方式
    这篇文章主要为大家展示了“springsecurity如何实现基于token的认证方式”,内容简而易懂,条理清晰,希望能够帮助大家解决疑惑,下面让小编带领大家一起研究并学习一下“springsecurity如何实现基于token的认证方式”...
    99+
    2023-06-20
  • SpringBoot登录验证token拦截器如何实现
    这篇文章主要讲解了“SpringBoot登录验证token拦截器如何实现”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“SpringBoot登录验证token拦截器如何实现”吧!用户访问接口验...
    99+
    2023-07-02
  • SpringBoot如何使用Sa-Token实现权限认证
    今天小编给大家分享一下SpringBoot如何使用Sa-Token实现权限认证的相关知识点,内容详细,逻辑清晰,相信大部分人都还太了解这方面的知识,所以分享这篇文章给大家参考一下,希望大家阅读完这篇文章后有所收获,下面我们一起来了解一下吧。...
    99+
    2023-07-06
  • vue中如何实现登录注册及token验证
    这篇文章主要介绍了vue中如何实现登录注册及token验证,具有一定借鉴价值,感兴趣的朋友可以参考下,希望大家阅读完这篇文章之后大有收获,下面让小编带着大家一起了解一下。具体实现代码如下:1. 利用rout...
    99+
    2024-04-02
  • Springboot 如何实现filter拦截token验证和跨域
    Springboot filter拦截token验证和跨域 背景 web验证授权合法的一般分为下面几种 使用session作为验证合法用户访问的验证方式 使用自己实...
    99+
    2024-04-02
  • Flask中基于Token的身份认证如何实现
    今天小编给大家分享一下Flask中基于Token的身份认证如何实现的相关知识点,内容详细,逻辑清晰,相信大部分人都还太了解这方面的知识,所以分享这篇文章给大家参考一下,希望大家阅读完这篇文章后有所收获,下面我们一起来了解一下吧。Flask提...
    99+
    2023-07-05
  • .net core api接口如何实现JWT方式认证Token
    这篇文章主要介绍.net core api接口如何实现JWT方式认证Token,文中介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们一定要看完!一、项目>管理Nuget包 安装二、.appsettings.js...
    99+
    2023-06-22
  • vue获取token实现token登录的示例代码
    使用token做登录验证的思路大致如下: 1、在第一次登录的时候前端调用后端的接口,把用户名和密码传给后端。 2、后端收到请求,验证用户名和密码,验证成功后,返回给前端一个token...
    99+
    2024-04-02
  • c#中token的使用方法实例
    目录token的存在意义使用方法token的存在意义 这是我初略了解的token的存在意义 用户使用用户名密码来请求服务器服务器进行验证用户的信息服务器通过验证发送给用户一个toke...
    99+
    2024-04-02
  • 如何实现 C/C++ 与 Python
    属于混合编程的问题。较全面的介绍一下,不仅限于题主提出的问题。以下讨论中,Python指它的标准实现,即CPython(虽然不是很严格) 本文分4个部分 1. C/C++ 调用 Python (基础篇)— 仅讨论Python官方提供的实...
    99+
    2023-01-31
    如何实现 Python
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作