黑莓手机论坛 一分快三技巧 - 绿色软件 - 绿色软件下载 - JZ5U绿色下载站 一分快三分析 九酷音乐网|好听的歌|网络歌曲|dj舞曲|流行歌曲大全 一分快三遗漏 软件下载_更快更安全的软件下载中心_2345软件大全(多特软件下载站)

令牌Token和会话Session原理与攻略

        本篇文章将从无到完整的登录框架或API详细讲述登录令牌原理、攻略等安全点。

        有些协议或框架也喜欢把令牌叫票据(Ticket),不论是APP还是Web浏览器,很多框架或协议都用到了本文所说的这套类似的认证机制(客户端各种加密用户名密码当我没说),这里的以Asp.net core下Web登录和验证为例子进行讲述,但原理攻略和语言、框架都无关。

 

目录:

一、过程与原理

二、Demo一分快三总代库结构

三、Demo源码介绍

四、构建与验证Token

五、Token失效与登录唯一性

六、CAS/SSO单点登录

七、URL授权验证与扫码登录

八、Session实现

九、关于Token刷新

 

本片文章Demo:https://github.com/chaoyebugao/AcctAuthDemo

 

 

一、过程与原理 

令牌授权过程
 

令牌机制简单过程(点击查看大图)

        首先,这套机制使用场景是登录授权和身份验证,可以用在Web上,也可以用在API的访问控制上。这套机制其实和很多无状态框架登录/授权验证协议类似,这里讲的其实和OAuth2.0里面授权码模式的原理是一样的(authorization code),只不过我们在这里将其步骤拆分,了解其原理和实现,以后搭建项目应用才能庖丁解牛。还有一点,很多框架的授权机制都太繁重且并不能灵活应用,这时候就可以自己搭一个。

        首先,用户使用终端向服务器提供可信凭证(一般登录是用户名密码,微信公众平台是appid+appsecret),服务端确认凭证正确,则返回授权的令牌(以下称Token)。这个Token是随机的字符串且与本次授权唯一相关。返回Token给终端的同时服务端也要一并保存Token,这样终端和服务端都只认Token,终端所有请求发送都需要携带此Token,服务端会验证和控制此Token。此时Token就有两个,一个是终端Token,一个是服务端Token,其中一个不对或没有,服务端都是拒绝的。

        举个例子,你上12306购票,购买过程就是授权你Token的过程,你的纸质票就是Token,另外一半对应的Token保存在12306那的DB里头,所有门闸就是网关,当你过门闸时会验证你Token是否对应DB的Token。你下车后,12306就把DB的Token标记处理掉,这样服务端就不会再认你手上的纸质票,票也就作废了。

        围绕这一机制,我们将讲述CAS单点登录、令牌授权与身份验证、Session实现、防重放攻击、登录唯一性、URL授权验证(用于验证邮箱等)等

 

 

二、Demo一分快三总代库结构

设备表:用于识别、记录不同的设备,同一设备应该有唯一的标记Id,下面详说

令牌表:用于持久化令牌,ExpireAt为过期时间,Token即令牌字符串,根据UserId与用户表相关联,根据DeviceId与设备表相关联

用户表:用户表,保存用户名密码等

设备表和设备标记(DeviceId)是可有可无的,可以根据实际业务来处理,有必要的话再增加其他相关联的一分快三总代和表。C/S或App的话DeviceId可以用系统的标识Id,像Web浏览器的话因为拿不到类似的东西,我们可以指定一个在Cookie里头,Demo就是这么干的。

 

 

三、Demo源码介绍

用户Controller 

HomeController

UserController - 用户注册、登录、注销登录

HomeController - Index - 默认启动页,Token验证页

 

 

四、构建与验证Token

Token构建

构建Token

验证Token

        Token的构建发生在用户提供的凭证(如用户名密码)被服务端确认无误之后。一次登录/授权的Token分两部分,服务端持有的我们叫一分快三总代库Token,用户端(Endpoint)持有的叫终端Token。终端Token可以是任意的随机字符串构成,所以这里最后要根据登录情况来求得哈希值即终端Token本身。因为后面要根据终端Token来查询处理一分快三总代库Token记录,所以他们必须有种关联,这种关联就是如上图所示,终端Token+设备Id得到的哈希值即一分快三总代库Token本身。

        可以看出,整个生成过程是单向不可逆的,验证也只能是单向验证,所以生成关系是这样的:

授权Token构建关系图

授权Token构建关系图

 

        这里有几点要注意的:

  • 终端Token应该有足够的长度,且每次应随机生成,因此才有Guid.NewGuid()参与求值
  • 终端Token参与生成的userId、name是起到了盐作用,让整个构建更加复杂(经提醒已经排除掉了密码的参与,哈希虽然很难破解但还是谨慎点好)
  • 不论是终端Token还是一分快三总代库Token都不应该可逆加密处理任何内容,因为可解密的话不论是终端还是一分快三总代库一分快三总代泄露的,都有被破解的风险,所以用哈希求值是最合适的
  • 构建一分快三总代库Token有deviceId参与,这样每次Token就只能是对应的deviceId才能被验证,这样就起了绑定作用。除了deviceId还可以绑定其他场景相关的,比如IP地址、终端类型
  • 日志最好不要记录任何Token

        两部分Token构建好之后,终端Token将被返回给终端,一分快三总代库Token持久化到服务端中。终端和一分快三总代库都要将各自的Token和场景信息持久化,Demo里面终端Token和deviceId放到了Cookie中。每次请求的终端都需要提交终端Token和绑定用的场景信息(deviceId),因为验证的时候一分快三总代库Token保存的是由它们哈希过来的值,因此验证的时候也是使用一样的构建过程(即Demo里面的BuildDatabaseToken方法),这样终端Token和一分快三总代库Token就有了对应关系。得到一分快三总代库Token就能在一分快三总代库里面查找了(即上图的loginTokenRepository.FindUser方法)。Demo的验证页面是Home/Index,里面使用了过滤器CheckLoginTokenActionFilterAttribute做验证,在需要验证的Controller或Action上做ServiceFilter属性标记处理即可。

        这里有几点要注意的:

  • 如果使用Http做接口且有App接入,不方便地支持Cookie机制的话可以改为放在请求头中
  • 如果使用Http且为Web浏览器,终端Token保存的Cookie应该设为HttpOnly,让JS不可触碰

        到这里童鞋们知道为什么Token拆成两部分了吗?整个Token授权过程是单向不可逆的,而且每个用户都有自己的哈希盐来生成Token,这样能避免哈希值被批量暴力破解,即使终端Token和一分快三总代库Token都泄露了你也对应不上。试想一下如果不是这样而是终端一分快三总代库的Token是相同的,那一旦一分快三总代库泄露那么黑客就能模拟Token进行登录/授权了。另外一分快三总代库Token哈希过后长度变短,查询性能也能提高,毕竟每个请求都需要进行验证,查询频率是很高的。

 

 

五、Token失效与登录唯一性

        不论是终端Token还是服务端Token都要有失效机制,时间越短越安全,但也要结合使用场景需求来设定时长。终端Token如果是Cookie的话直接用Cookie的过期时间即可,并且要和一分快三总代库Token的过期时间一致。一分快三总代库Token生成的时候也要指定过期时间,Demo里面一分快三总代库保存的字段为ExpireAt。一般有以下几种失效情况:

  • 到了过期时间
  • 用户修改账户关键信息,服务端需要主动将旧的Token全部作废掉,如修改密码
  • 用户注销登录
  • 用户使用Token刷新机制

        另外类似的,如果需求是只能一种终端一个登录,比如Web和App可以保持同时登录但App只能有一个登录,一分快三总代库Token还得绑定“终端类型”,这样在最新一次登录的时候把相同的终端类型的旧的一分快三总代库Token全部作废掉就好了。如果账号只能有一个登录,那什么都不绑定,同一时间只保持最新一个Token有效即可。

        可以看出,服务端的保有的一分快三总代库Token可以有效控制其授权,达到访问控制的目的。

 

 

六、CAS/SSO单点登录

        CAS即中央认证服务,SSO即单点登录。很多时候这两个会放在一起说,其实CAS是一套解决方案,SSO是一种机制描述。如果我们使用的是Http-Web那么我们如何实现我们自己的SSO呢?很简单,把Token和绑定的场景信息提升到同一个域下即可。比如有总部和门店两个系统分别使用了hq.xxxx.com/store.xxxx.com子域名,那不管从哪个系统登录,login_token和deviceId这两个Cookie放在顶级域.xxxx.com下即可,这样所有子系统都能访问得到它们,继而都保有登录/授权状态。有没有发现登录新浪微博后,输入weibo.com都会先跳转到sso然后再跳转回来,这个也差不多,这也是为什么你登录了新浪微博,你新浪一分快三走势图也是登录了的状态。

 

 

七、URL授权验证与扫码登录

        当我们需要进行邮箱验证的时候,有可能是用户登录和邮箱不是一个终端的,这时候我们就需要进行URL授权验证来避免用户再次进行登录。其原理很简单,在用户点击验证的链接上面附上URL授权令牌即可(下面简称URL Token),这个URL Token与登录Token不应该有关系所以应当单独保存。生成一个URL Token,服务端再对应保存类似的服务端Token,这样就有了【URL Token】 - 【服务端Token】 - 【用户】这样的对应关系。当用户在有效期内点击后,服务端获得URL Token也就能进行授权或验证。

        扫码登录的场景复杂一些,终端生成的二维码其实就是一个Token(我们称之为QR Token)这个Token是和终端绑定的。用户拿App扫了QR码,其实就是在App内同时提交QR Token和用户信息,用户确认可以登录后服务端会颁发登录Token给终端,这样终端就是登录状态了,这一步也就是上面构建和验证登录Token的过程。实际扫码登录需要实现即时通讯,这样终端才能做出相应的反应。另外QR Token也是一样有过期时间的,因此那些扫码登录的页面会做二维码自动刷新的。

 

 

八、Session实现

        其实有些童鞋会纳闷,完善的框架都会提供Session操作,其原理是一样的,那为什么我们还这么“造作”呢?原因有二,框架自带的可能过重,比如我就很不喜欢asp.net自带的授权认证机制,微软弄得一套一套的,简直就是全家桶,笨重,自己实现一个能定制化且轻量。第二,考虑类似上面的功能实现,自己做能更灵活地实现。

        我们已经实现了登录/授权和验证,接下来我们只要想办法把一些一分快三总代和Token绑定在一起,并放在缓存中,这些一分快三总代就是Session了。我一般的做法是封装一个SessionService,然后定义一套Session接口。一个Session一分快三总代由TokenKey-Value组成,如果Token失效,则清理所有对应的TokenKey一分快三总代即可。就是这么简单粗暴,不同的缓存组件实现不尽相同。

 

 

九、关于Token刷新

        OAuth 2.0里面有提供Token刷新服务,即终端持有的Token快过期的时候,终端可以再调用刷新接口来替换快过期的Token,达到永续状态。简单来说就是请求新的Token,请求时旧Token作废掉,实现并不复杂,参见:Oauth2.0(三):Access Token 与 Refresh Token

 

 

十、防重放攻击与签名机制

        重放攻击(Replay Attacks)又叫重播攻击,防范这个其实和本文讨论的主题没关系。完整实现的接口都有实现,欲知详情,等我下一篇。

 

        花了好几天来写了这篇文章,同时也是自己对这一技术点的总结归纳,有不对的地方还请指正。

 

相关链接:

ASP.NET Web API与Owin OAuth:调用与用户相关的Web API

微信公众平台技术文档 - 获取access_token

posted @ 2019-05-15 19:56 朝野布告 阅读(...) 评论(...) 编辑 收藏