常见的鉴权方式有两种,一种是基于session,另一种是基于token方式的鉴权,我们来浅谈一下两种 鉴权方式的区别。

两种鉴权方式对比

session

  1. 安全性:session是基于cookie进行用户识别的,cookie如果被截获,用户很容易受到跨站请求伪造的攻击。
  2. 扩展性:session是有状态的,是具有IP黏贴性和有中心化特性的,在分布式环境下,虽然每台服务器业务逻辑一样,但是session是保存在各个服务器中的,而且每个服务器内存是不共享的,如果使用session去实现分布式部署的话,需要使用其他的一些技术手段去实现,比如spring session,将session保存在第三方服务中,比如redis,这样一旦第三方服务出现问题,整个验权系统就会奔溃,在电商系统及高并发系统中的集群化处理显然是不合适的。
  3. 抗压能力:通常session是存储在内存中的,每个用户通过认证后都会将session存储在服务器内存中,当用户量增大的情况下服务器的压力也随之增大。

token

  1. 安全性:浏览器会将接收到的token值存储在Local Storage中,(通过js代码写入Local Storage,通过js获取,并不会像cookie一样自动携带)
  2. 扩展性:token是无状态的,是去中心化的,在分布式环境下,各个服务器中的服务只对token进行数据查询,它不需要在服务端保留用户信息或者会话信息,这意味着用户不需要考虑登录的是哪一台服务器,高效的解决了session扩展性的弊端。
  3. 抗压能力:token与session的不同主要在认证成功后,会对当前用户数据进行加密,生成一个加密字符串token,返还给客户端(服务器端并不进行保存)

基于token的鉴权方式

业界常用的授权标准有两种,一种是使用auth2,这种方式更适合于类似第三方授权登录,比如微信、微博、QQ信任登录业务。另一种是oauth,即第三方无需知道用户和密码就可以申请获得该资源的授权,更适用于对用户的权限校验并分配访问权限,比如常见的登录后分配可见资源(按钮、菜单等)类型网站。

Javashop电商系统 采用的是oauth方式的鉴权标准。我们以系统的应用为例来介绍oauth的方案。

1. 登录
服务端校验密码,成功后返回access_token和refresh_token,客户端记录上述token。
2. 访问API
在访问API之前解析access_token,并且查看是否过期,如果不过 期则请求API,如果过期,则要刷新令牌,在请求API。
3. 刷新token
携带有效期的refresh_token换回有效token,如果refresh_token过期,则需要用户重新登录。
4. 注销
请求注销api,服务器端和客户端应同时删除token的存储。

1. 客户端请求API
携带access_token信息,如果生成环境不会直接携带access_token,会使用加密后的签名校验。祥见以下防重放机制。
2. 获取token
根据环境不同而有不同的获取token方式。
3. 解析token
通过JWT工具将token解析。
4. 由redis读取token
根据uid拼接key读取access_token, 如果不存在这个用户的token说明已经登出。
5. 验证token
判断次token是否属于此uid,判断token是否过期,如果过期则进行以下刷新token的流程。
6. 注入权限
如果token验证成功,根据user信息生成权限注入到spring安全上下文中。

刷新token流程

1. 客户端请求API
携带refresh_token,如果是生产环境不会直接携带refresh_token信息,详见以下防重放攻击。
2. 获取token
根据环境不同而有不同的获取token方式。
3. 解析token
通过JWT工具将token解析。
4. token读取
根据uid拼接key读取出access_token,如果不存在这个用户的token说明用户已经登出。
5. 验证token
判断此token是否属于此uid,判断token是否已经过期,如果过期,则返回refresh_token过期错误,此时用户需要重新登录。
6. 刷新token
如果refresh_token 验证成功,则重新生成access_token和refresh_token,上述有效期以当前时间向后计算,替换此用户在redis中的token,并将token返回给客户端。

防重放机制

一、 参数的读取
1. 在生产环境时,不能直接传递token,而是要传递签名数据,服务器端验签后由Redis中获取签名。
2. 如果是非生产环境,直接由header中读取token。
二、 生产环境传递如下参数
memberid (用户id)
nonce(随机字串,6位)
timestamp(当前时间戳,到秒)
sign= md5( uid+ nonce + timestamp +token )
三、 验证逻辑
1. 验证时间戳
判断时间戳是否起过60s,大于60s则判别为重放攻击。

2. 验证nonce
首先验证nonce在 reids中是否存在,如果存在,则判别为重放攻击,否则将nonce记录在redis中(key为:"nonce"+uid+"_"+nonce),失效时间为60s。
3. 验证sign
md5( uid+ nonce + timestamp +token ) 验证是签名是否通过。
4. 验证token
通过uid拿到token ,验证逻辑同验权流程。

当然在不同的业务场景下实现方案是多种多样的,仅以此方案抛砖引玉,供大家参考。

易族智汇(javashop)原创文章

基于token机制鉴权架构的更多相关文章

  1. Session, Token, OAuth 鉴权那些事儿

    鉴权那些事 整体思路 无论什么样的服务, Web 服务总是不能绕开鉴权这个话题的, 通过有效的鉴权手段来保护网站数据, 来为特定用户提供服务. 整体来说, 有三种方式: Session-Cookie ...

  2. SpringBoot使用token简单鉴权

    本文使用SpringBoot结合Redis进行简单的token鉴权. 1.简介 刚刚换了公司,所以最近有些忙碌,所以一直没有什么产出,最近朋友问我登录相关的,所以这里先写一篇简单使用token鉴权的文 ...

  3. 基于SpringAop的鉴权功能

    什么是 AOP 首先我们先了解一下什么是AOP,AOP(Aspect Orient Programming),直译过来就是面向切面编程.AOP是一种编程思想,是面向对象编程(OOP)的一种补充.面向对 ...

  4. 基于HA机制的MyCat架构——配置HAProxy

    HAProxy简介HAProxy提供高可用性.负载均衡以及基于TCP和HTTP应用的代理,支持虚拟主机,它是免费.快速并且可靠的一种解决方案. HAProxy特别适用于那些负载特大的web站点,这些站 ...

  5. 认证鉴权与API权限控制在微服务架构中的设计与实现(四)

    引言: 本文系<认证鉴权与API权限控制在微服务架构中的设计与实现>系列的完结篇,前面三篇已经将认证鉴权与API权限控制的流程和主要细节讲解完.本文比较长,对这个系列进行收尾,主要内容包括 ...

  6. shiro jwt 构建无状态分布式鉴权体系

    一:JWT 1.令牌构造 JWT(json web token)是可在网络上传输的用于声明某种主张的令牌(token),以JSON 对象为载体的轻量级开放标准(RFC 7519). 一个JWT令牌的定 ...

  7. 【Spring Cloud & Alibaba 实战 | 总结篇】Spring Cloud Gateway + Spring Security OAuth2 + JWT 实现微服务统一认证授权和鉴权

    一. 前言 hi,大家好~ 好久没更文了,期间主要致力于项目的功能升级和问题修复中,经过一年时间的打磨,[有来]终于迎来v2.0版本,相较于v1.x版本主要完善了OAuth2认证授权.鉴权的逻辑,结合 ...

  8. SpringBoot系列: Web应用鉴权思路

    ==============================web 项目鉴权============================== 主要的鉴权方式有:1. 用户名/密码鉴权, 然后通过 Sess ...

  9. Mongodb 认证鉴权那点事

    [TOC] 一.Mongodb 的权限管理 认识权限管理,说明主要概念及关系 与大多数数据库一样,Mongodb同样提供了一套权限管理机制. 为了体验Mongodb 的权限管理,我们找一台已经安装好的 ...

随机推荐

  1. JAVA描述算法和数据结构(01):稀疏数组和二维数组转换

    本文源码:GitHub·点这里 || GitEE·点这里 一.基本简介 1.基础概念 在矩阵中,若数值为0的元素数目远远多于非0元素的数目,并且非0元素分布没有规律时,则称该矩阵为稀疏矩阵:与之相反, ...

  2. java基础(3):变量、运算符

    1. 变量 1.1 变量概述 前面我们已经学习了常量,接下来我们要学习变量.在Java中变量的应用比常量的应用要多很多.所以变量也是尤为重要的知识点! 什么是变量?变量是一个内存中的小盒子(小容器), ...

  3. python爬虫-京东商品爬取

    京东商品爬取 仅供学习 一.使用selenium from selenium import webdriver from selenium.webdriver.common.keys import K ...

  4. IDEA中安装EasyCode插件并连接数据库生成代码

    场景 EasyCode是基于IntelliJ IDEA开发的代码生成插件,支持自定义任意模板(Java,html,js,xml).只要是与数据库相关的代码都可以通过自定义模板来生成.支持数据库类型与j ...

  5. GIT命令行统计代码提交行数

    项目中遇到写报告的时候要反馈某个人或者某个功能的代码量,又没有集成CI这些插件,可以简单的用GIT命令统计下代码提交量: --统计某个人的提交代码 git log --author="old ...

  6. Masonry纯码实现UIScrollView 之上下滚动,设置UIScrollView背景图片

    参考链接:https://www.jianshu.com/p/9a158308c50b 亲测有效,很赞! 你们最想要的Demo下载地址:https://github.com/objcxiaobai/C ...

  7. Django—开发具体流程

    1.创建Django项目 [root@localhost ~]# django-admin startproject 项目名 [root@localhost ~]# django-admin star ...

  8. Scrapy_redis

    简介 scrapy_redis是一个基于Redis的Scrapy组件,用于scrapy项目的分布式部署和开发 你可以启动多个spider对象,互相之间共享有一个redis的request队列,最适合多 ...

  9. 201871010102-常龙龙《面向对象程序设计(java)》第十六周学习总结

    项目 内容 这个作业属于哪个课程 https://www.cnblogs.com/nwnu-daizh/ 这个作业的要求在哪里 https://www.cnblogs.com/nwnu-daizh/p ...

  10. 201871010113-刘兴瑞《面向对象程序设计(java)》第十六周学习总结

    项目 内容 这个作业属于哪个课程 <任课教师博客主页链接>https://www.cnblogs.com/nwnu-daizh/ 这个作业的要求在哪里 <作业链接地址>http ...