在前后端分离的项目中,首先我们要解决的问题就是身份认证

以往的时候,我们使用cookie+session,或者只用cookie来保持会话。

一,先来复习一下cookie和session

首先我们来复习一下在aspnet中cookie和session的关系,做一个简单试验

这是一个普通的view没有任何处理

可以看到,没有任何东西(cookie),然后当我们写入一个session之后

会发现多了一个名为ASP.NET_SessionId的cookie。我们都知道在aspnet中,session是保存在服务器端的内存中的,而http协议是无状态的,那么他是怎么确定不同请求的session

没错,session是借助cookie来实现的:cookie中保存着 session的key,当我们清除掉浏览器缓存时,会发现session也找不到了,就是这个原因。

使用session来保持会话有几个很严重的缺点:1 session容易丢失;2无法支持分布式;3,cookie 对跨域的支持不好

所以就用到了我们今天说的token

二,token 

1,token的产生

一般是用户登录成功,服务器端产生一个token并返给前端,前端将token保存在cookie或者localStorage里面,然后每次请求时都带上这个token,一般都带在请求头里面

 2,token的内容

一般的token里面必须有的是:1,会话用户的标识:比如userid。2,token的过期时间,如果想更完整一点,可以加上token的颁发者,签名等等

3,token的生成算法,一般是由服务器端将token的主要内容,过期时间等等做非对称加密,然后进行签名算法(防止客户端更改),具体看后面jwt

4,token校验

当服务器端收到请求时,首先会校验token,校验有两种不同的方式

 一, token产生后保存在服务器端(redis或者其他比较速度快的缓存中) 。优点:可控性强,可以用这个来做单点登录,比如另一个地方登录,就remove掉之前的token。缺点:实现麻烦一点,而且要占服务器压力

二, token产生后服务器端不保存,只负责校验。 优点:大大降低了服务器的压力,实现起来,也要相对简单一点。缺点:token一旦颁发,服务器端就不可控了,只能等它过期。

    具体用哪种看具体的需求。如果不是做可控性要求很强,个人建议第二种。

5 jwt 

jwt 全名Json Web Tokens,算是一种token的规范吧

园子里面有很不不错的介绍 ,比如这篇:阮一峰 jwt介绍   http://www.ruanyifeng.com/blog/2018/07/json_web_token-tutorial.html

 

组成有三部分

  • Header(头部,一般包含了token的签名方式)
  • Payload(负载,也就是具体的有效部分)
  • Signature(签名,将前两部分进行签名算法,防止客户端篡改)

实现方式,将header部分和payload部分分别进行base64算法,然后用点号“.”隔开拼接,然后进行签名算法,然后在将三部分拼接(点号隔开)就得到了jwt

注意 ,jwt默认是采用base64编码的,也就是说 客户端也能解码得出具体内容的,所以除非特殊情况,重要敏感字段一定不能放在token中

以下是具体实现

using System;
using System.Collections.Generic;
using System.Linq;
using System.Security.Cryptography;
using System.Text;
using System.Web;namespace Rk.JWT
{public class Jwt{//参考自 阮一峰 jwt介绍  http://www.ruanyifeng.com/blog/2018/07/json_web_token-tutorial.htmlpublic static string SALT = "OXpcRP8jmCfMKumY";/// <summary>////// </summary>/// <param name="ExraPayload">额外的信息</param>/// <returns></returns>public static string Create(Dictionary<string,object> ExraPayload){var Header = new Dictionary<string, string>();Header.Add("tp", "MD5");var Payload = new Dictionary<string, object>();//JWT 规定了7个官方字段,供选用。Payload.Add("iss", "signBy"); //颁发人Payload.Add("jti", Guid.NewGuid().ToString()); //jwt的idPayload.Add("exp",System.DateTime.Now.AddMinutes(20));//过期时间Payload.Add("nbf", System.DateTime.Now);//生效时间Payload.Add("iat", System.DateTime.Now);//签发时间Payload.Add("sub", "subject");//主题Payload.Add("aud", "audience");//受众foreach (var item in ExraPayload){if (Payload.ContainsKey(item.Key)){throw new Exception($"{item.Key}键值已被占用 不能使用 ");}else{Payload.Add(item.Key, item.Value);}}string base64Header = Base64Url(Newtonsoft.Json.JsonConvert.SerializeObject(Header));string base64Payload = Base64Url(Newtonsoft.Json.JsonConvert.SerializeObject(Payload));string tmp = base64Header + "." + base64Payload;string sign = Md5(tmp+ SALT);//加盐,重要return base64Header+"."+ base64Payload+"."+ sign;}//校验是否合法,是否过期public static bool Check(string token){string base64Header = token.Split('.')[0];string base64Payload = token.Split('.')[1];string sign = token.Split('.')[2];string tmp = base64Header + "." + base64Payload;var signCheck = Md5(base64Header + "." + base64Payload + SALT);if(signCheck!= sign){return false;}var dic = Newtonsoft.Json.JsonConvert.DeserializeObject<Dictionary<string, object>>(Base64UrlDecode(base64Payload));if(  Convert.ToDateTime(dic["exp"])<System.DateTime.Now){//过期了return false;}return true;}//校验是否合法,是否过期public static Dictionary<string,object> GetPayLoad(string token){string base64Payload = token.Split('.')[1];var dic = Newtonsoft.Json.JsonConvert.DeserializeObject<Dictionary<string, object>>(Base64UrlDecode(base64Payload));return dic;}public static string Base64Url(string input){//JWT 作为一个令牌(token),有些场合可能会放到 URL(比如 api.example.com/?token=xxx)。//Base64 有三个字符+、/和=,在 URL 里面有特殊含义,所以要被替换掉:=被省略、+替换成-,/替换成_ 。string output = "";byte[] bytes = Encoding.UTF8.GetBytes(input);try{output = Convert.ToBase64String(bytes).Replace('+', '-').Replace('/', '_').TrimEnd('=') ;}catch (Exception e){throw e;}return output;}public static string Base64UrlDecode(string input){string output = "";input = input.Replace('-', '+').Replace('_', '/');switch (input.Length % 4){case 2:input += "==";break;case 3:input += "=";break;}byte[] bytes = Convert.FromBase64String(input);try{output = Encoding.UTF8.GetString(bytes);}catch{output = input;}return output;}public static string Md5(string input,int bit=16){MD5CryptoServiceProvider md5Hasher = new MD5CryptoServiceProvider();byte[] hashedDataBytes;hashedDataBytes = md5Hasher.ComputeHash(Encoding.GetEncoding("gb2312").GetBytes(input));StringBuilder tmp = new StringBuilder();foreach (byte i in hashedDataBytes){tmp.Append(i.ToString("x2"));}if (bit == 16)return tmp.ToString().Substring(8, 16);elseif (bit == 32) return tmp.ToString();//默认情况else return string.Empty;}}}

  

使用方式

public class HomeController : BaseController{public ActionResult Login(string username, string pwd){/// 1, todo 验证用户名密码正确//2,//在token中加入用户id,创建tokenvar dic = new Dictionary<string, object>();dic.Add("userid", "20125521225858");string token = JWT.Jwt.Create(dic);//验证token是否正确是否过期var isChecked = JWT.Jwt.Check(token);return Content("");}}

  

下一篇我们将会聊一聊 rest 风格url在前后端分离项目中的使用

转载于:https://www.cnblogs.com/wahson2019/p/10860973.html

Aspnet Mvc 前后端分离项目手记(二)关于token认证相关推荐

  1. Java网络商城项目 SpringBoot+SpringCloud+Vue 网络商城(SSM前后端分离项目)二十二(下单和微信支付)

    Java网络商城项目 SpringBoot+SpringCloud+Vue 网络商城(SSM前后端分离项目)二十(下单) 0.学习目标 会调用订单系统接口 实现订单结算功能 实现微信支付功能 1.订单 ...

  2. Java前后端分离项目生成二维码链接带中文参数遇到的问题及解决办法

    遇到的问题 最近项目做二维码分享链接过程中遇到了个小问题,使用Java后端生成二维码链接时,当拼接的参数中带有中文,使用手机浏览器扫码正常,但是用微信扫码,url中的中文被和谐掉了,导致页面显示有问题 ...

  3. B站云E办Vue+SpringBoot前后端分离项目——MVC三层架构搭建后台项目

    本项目来源B站云E办,笔记整理了项目搭建的过程和涉及的知识点.对于学习来说,不是复制粘贴代码即可,要知其然知其所以然.希望我的笔记能为大家提供思路,也欢迎各位伙伴的指正. 项目前端学习笔记目录 B站云 ...

  4. 前后端分离项目—微信小程序的创建及app.json的配置(二)

    目录 4.创建微信小程序项目 4.1获取appid 5.配置app.json 5.1添加页面 5.2修改顶部框样式 5.3添加taber底部导航栏 本人框架入门,此处记录完成一个前后端分离项目笔记,若 ...

  5. 从0搭建一个Springboot+vue前后端分离项目(一)安装工具,创建项目

    从0搭建一个Springboot+vue前后端分离项目(二)使用idea进行页面搭建+页面搭建 参考学习vue官网文档 https://v3.cn.vuejs.org/guide/installati ...

  6. crm开源系统 tp框架_八个开源的 Spring Boot 前后端分离项目,一定要收藏!

    点击蓝色字关注我们 前后端分离已经在慢慢走进各公司的技术栈,不少公司都已经切换到这个技术栈上面了.即使贵司目前没有切换到这个技术栈上面,也非常建议大家学习一下前后端分离开发,以免在公司干了两三年,SS ...

  7. [软技能] 在前后端分离项目里,请说说前端传递的token的流程?

    [软技能] 在前后端分离项目里,请说说前端传递的token的流程? (一):cookie前端 post 账号密码,后端 response header: set-cookie, 将 token 插入 ...

  8. 前后端分离项目,后端是如何处理前端传递的token?

    前后端分离项目中,在不使用 SpringSecurity.Shiro 安全框架的情况下,后端是如何处理前段传递的 token 的呢? 简单说一个场景,在一个非常小的项目中,由于业务逻辑比较简单,也没有 ...

  9. RuoYi-Vue 部署 Linux环境 若依前后端分离项目(jar包+nginx 单机版本)

    文章目录 一.软件安装部署 1. 安装jdk 2. mysql8安装部署 3. redis安装 4. nginx 安装部署 5. 克隆项目 二.后端项目 2.1. 修改数据库连接 2.2. 修改Red ...

  10. php node.js django,Vue.js和Django搭建前后端分离项目示例详解

    本篇文章主要介绍了Django+Vue.js搭建前后端分离项目的示例,具有一定参考价值,有兴趣的可以了解一下 在写这篇文章的时候,顺带学习了一下关于Markdown的使用方法. 笔者是个渣渣,一切都是 ...

最新文章

  1. mysql编写完怎么执行_面试官:一条MySQL更新语句是如何执行的?
  2. scvmm live migration issue
  3. 新西兰激光事故5年增加130% 官员警告危害航空安全
  4. centos7安装mysql日志空白_centos7安装Mysql爬坑记录 - G
  5. BZOJ 4817: [Sdoi2017]树点涂色
  6. Retrofit2/OkHttp 重写覆盖headers 与 不重写覆盖Headers
  7. vue 小地图放大缩小_实景3D卫星地图
  8. 基于FPGA实现压缩算法
  9. delphi连接mysql不用添加dsn_jsp中有没有像asp的非DSN连接数据库方法呢?(20分)
  10. 使用双向链表构建二叉树_python:26.二叉搜索树与双向链表
  11. java虚拟机之垃圾回收器
  12. 《python学习手册》目录
  13. 关于大学生请假规定制度(五篇)
  14. 我的大学 --- 郭天祥【3】
  15. win10中MySQL5.7重置密码
  16. linux创建lvm分区命令,CentOS下LVM的创建与使用
  17. 如何对谷歌地图的火星坐标进行纠偏校正
  18. Spring Cloud Gateway 服务网关的部署与使用详细介绍
  19. TK1 刷机教程---使用JETPACK
  20. 网页认证上网服务器无响应,portal认证失败,网络故障或者portal服务器没有响应排查方法...

热门文章

  1. 基于北斗观测值的智能手机GNSS定位研究
  2. 怎么把计算机管理的磁盘找出来,电脑分区显示不出来怎么办
  3. 拥有百万粉丝的大牛讲述学Android的历程程。看看你缺了哪些?
  4. 柳下惠_拔剑-浆糊的传说_新浪博客
  5. 出价成本计算机软件,百度竞价推广中,关键词怎么出价可以降低成本?
  6. Python编程:从入门到实践第二版答案(第七章)
  7. 活动|域名转入专场活动
  8. 电商运营分享:关于双11的淘宝客无节操赚钱干货
  9. 安卓开发——MaterialDesign实战
  10. openbsd_OpenBSD与Linux,Gentoo与Microsoft相遇