我的编程空间,编程开发者的网络收藏夹
学习永远不晚

C# 如何实现Token

短信预约 -IT技能 免费直播动态提醒
省份

北京

  • 北京
  • 上海
  • 天津
  • 重庆
  • 河北
  • 山东
  • 辽宁
  • 黑龙江
  • 吉林
  • 甘肃
  • 青海
  • 河南
  • 江苏
  • 湖北
  • 湖南
  • 江西
  • 浙江
  • 广东
  • 云南
  • 福建
  • 海南
  • 山西
  • 四川
  • 陕西
  • 贵州
  • 安徽
  • 广西
  • 内蒙
  • 西藏
  • 新疆
  • 宁夏
  • 兵团
手机号立即预约

请填写图片验证码后获取短信验证码

看不清楚,换张图片

免费获取短信验证码

C# 如何实现Token

什么是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的资料请关注编程网其它相关文章!

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

C# 如何实现Token

下载Word文档到电脑,方便收藏和打印~

下载Word文档

猜你喜欢

SpringBoot如何实现token登录

这篇文章主要为大家展示了“SpringBoot如何实现token登录”,内容简而易懂,条理清晰,希望能够帮助大家解决疑惑,下面让小编带领大家一起研究并学习一下“SpringBoot如何实现token登录”这篇文章吧。为什么引入token机制
2023-06-29

C# 怎么实现Token的方法

本篇内容介绍了“C# 怎么实现Token的方法”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!什么是JWTJWT:Json web token
2023-06-14

Java如何实现Token登录验证

这篇文章主要介绍“Java如何实现Token登录验证”,在日常操作中,相信很多人在Java如何实现Token登录验证问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”Java如何实现Token登录验证”的疑惑有所
2023-07-05

php如何实现响应头增加token

这篇文章主要介绍“php如何实现响应头增加token”,在日常操作中,相信很多人在php如何实现响应头增加token问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”php如何实现响应头增加token”的疑惑有所
2023-07-05

PHP如何实现JWT的Token登录认证

本篇内容介绍了“PHP如何实现JWT的Token登录认证”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!1、JWT简介JSON Web Tok
2023-06-21

springsecurity如何实现基于token的认证方式

这篇文章主要为大家展示了“springsecurity如何实现基于token的认证方式”,内容简而易懂,条理清晰,希望能够帮助大家解决疑惑,下面让小编带领大家一起研究并学习一下“springsecurity如何实现基于token的认证方式”
2023-06-20

SpringBoot登录验证token拦截器如何实现

这篇文章主要讲解了“SpringBoot登录验证token拦截器如何实现”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“SpringBoot登录验证token拦截器如何实现”吧!用户访问接口验
2023-07-02

SpringBoot如何使用Sa-Token实现权限认证

今天小编给大家分享一下SpringBoot如何使用Sa-Token实现权限认证的相关知识点,内容详细,逻辑清晰,相信大部分人都还太了解这方面的知识,所以分享这篇文章给大家参考一下,希望大家阅读完这篇文章后有所收获,下面我们一起来了解一下吧。
2023-07-06

Flask中基于Token的身份认证如何实现

今天小编给大家分享一下Flask中基于Token的身份认证如何实现的相关知识点,内容详细,逻辑清晰,相信大部分人都还太了解这方面的知识,所以分享这篇文章给大家参考一下,希望大家阅读完这篇文章后有所收获,下面我们一起来了解一下吧。Flask提
2023-07-05

.net core api接口如何实现JWT方式认证Token

这篇文章主要介绍.net core api接口如何实现JWT方式认证Token,文中介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们一定要看完!一、项目>管理Nuget包 安装二、.appsettings.json添加"JWT": {
2023-06-22

如何实现 C/C++ 与 Python

属于混合编程的问题。较全面的介绍一下,不仅限于题主提出的问题。以下讨论中,Python指它的标准实现,即CPython(虽然不是很严格)本文分4个部分1. C/C++ 调用 Python (基础篇)— 仅讨论Python官方提供的实现方式
2023-01-31

编程热搜

  • Python 学习之路 - Python
    一、安装Python34Windows在Python官网(https://www.python.org/downloads/)下载安装包并安装。Python的默认安装路径是:C:\Python34配置环境变量:【右键计算机】--》【属性】-
    Python 学习之路 - Python
  • chatgpt的中文全称是什么
    chatgpt的中文全称是生成型预训练变换模型。ChatGPT是什么ChatGPT是美国人工智能研究实验室OpenAI开发的一种全新聊天机器人模型,它能够通过学习和理解人类的语言来进行对话,还能根据聊天的上下文进行互动,并协助人类完成一系列
    chatgpt的中文全称是什么
  • C/C++中extern函数使用详解
  • C/C++可变参数的使用
    可变参数的使用方法远远不止以下几种,不过在C,C++中使用可变参数时要小心,在使用printf()等函数时传入的参数个数一定不能比前面的格式化字符串中的’%’符号个数少,否则会产生访问越界,运气不好的话还会导致程序崩溃
    C/C++可变参数的使用
  • css样式文件该放在哪里
  • php中数组下标必须是连续的吗
  • Python 3 教程
    Python 3 教程 Python 的 3.0 版本,常被称为 Python 3000,或简称 Py3k。相对于 Python 的早期版本,这是一个较大的升级。为了不带入过多的累赘,Python 3.0 在设计的时候没有考虑向下兼容。 Python
    Python 3 教程
  • Python pip包管理
    一、前言    在Python中, 安装第三方模块是通过 setuptools 这个工具完成的。 Python有两个封装了 setuptools的包管理工具: easy_install  和  pip , 目前官方推荐使用 pip。    
    Python pip包管理
  • ubuntu如何重新编译内核
  • 改善Java代码之慎用java动态编译

目录