作者介绍

张龙(zero),一线运维老鸟。致力于LINUX/PYTHON/开源技术研究。

常见认证方法

首先要明白,认证和授权是不同的。认证是判定用户的合法性,授权是判定用户的权限级别是否可执行后续操作。这里所讲的仅含认证。

basic认证

这是http协议中所带带基本认证,是一种简单为上的认证方式。原理是在每个请求的header中添加用户名和密码的字符串(格式为“username:password”,用base64编码)。这种方式相当于将“用户名:密码”绑定为一个开放式证书,这会有几个问题:

1.每次请求都需要用户名密码,如果此连接未使用SSL/TLS,或加密被破解,用户名密码基本就暴露了

2.无法注销用户的登录状态

3.证书不会过期,除非修改密码。

cookie

将认证的结果存在客户端的cookie中,通过检查cookie中的身份信息来作为认证结果。这种方式的特点是便捷,且只需要一次认证,多次可用;也可以注销登录状态和设置过期时间;甚至也有办法(比如设置httpOnly)来避免XSS攻击。但它的缺点十分明显,使用cookie那便是有状态的服务了。

JWT

JWT协议似乎已经应用十分广泛,JSON Web Token——一种基于token的json格式web认证方法。基本的原理是,第一次认证通过用户名密码,服务端签发一个json格式的token。后续客户端的请求都携带这个token,服务端仅需要解析这个token,来判别客户端的身份和合法性。而JWT协议仅仅规定了这个协议的格式(RFC7519),它的序列生成方法在JWS协议中描述(https://tools.ietf.org/html/rfc7515),分为三个部分:

header头部

header头部主要用于声明类型,这里是jwt,声明加密的算法 通常直接使用 HMAC SHA256。一种常见的头部是这样的:

{

'typ': 'JWT',

'alg': 'HS256'

}

1

2

3

4

{

'typ':'JWT',

'alg':'HS256'

}

payload负荷

payload是放置实际有效使用信息的地方。JWT定义了几种内容,包括:标准中注册的声明,如签发者,接收者,有效时间(exp),时间戳(iat,issued at)等;为官方建议但非必须公共声明私有声明         一个常见的payload是这样的:

{'user_id': 123456,

'user_role': admin,

'iat': 1467255177

}

1

2

3

4

{'user_id':123456,

'user_role':admin,

'iat':1467255177

}

事实上,payload中的内容是自由的,按照自己开发的需要加入。

有个小问题。使用itsdangerous包的TimedJSONWebSignatureSerializer进行token序列生成的结果,exp是在头部里的。这里似乎违背了jwt的协议规则。

实现JWT

如何生成token

这里使用python模块itsdangerous,这个模块能做很多编码工作,其中一个是实现JWS的token序列。         genTokenSeq这个函数用于生成token。其中使用的是TimedJSONWebSignatureSerializer进行序列的生成,这里secretkey密钥、salt盐值从配置文件中读取,当然也可以直接写死在这里。expiresin是超时时间间隔,这个间隔以秒记,可以直接在这里设置,选择将其设为方法的形参。

# serializer for JWT

from itsdangerous import TimedJSONWebSignatureSerializer as Serializer

def genTokenSeq(self, expires):

s = Serializer(

secret_key=app.config['SECRET_KEY'],

salt=app.config['AUTH_SALT'],

expires_in=expires)

timestamp = time.time()

return s.dumps(

{'user_id': self.user_id,

'user_role': self.role_id,

'iat': timestamp})

1

2

3

4

5

6

7

8

9

10

11

12

# serializer for JWT

fromitsdangerousimportTimedJSONWebSignatureSerializerasSerializer

defgenTokenSeq(self,expires):

s=Serializer(

secret_key=app.config['SECRET_KEY'],

salt=app.config['AUTH_SALT'],

expires_in=expires)

timestamp=time.time()

returns.dumps(

{'user_id':self.user_id,

'user_role':self.role_id,

'iat':timestamp})

使用Serializer可以帮我们处理好header、signature的问题。我们只需要用s.dumps将payload的内容写进来。这里准备在每个token中写入三个值:用户id、用户角色id和当前时间(‘iat’是JWT标准注册声明中的一项)。

解析token

解析需要使用到同样的serializer,配置一样的secret key和salt,使用loads方法来解析token。itsdangerous提供了各种异常处理类,用起来也很方便。

如果是SignatureExpired,则可以直接返回过期;

如果是BadSignature,则代表了所有其他签名错误的情况,于是又分为:

能读取到payload:那么这个消息是一个内容被篡改、消息体加密过程正确的消息secret key和salt很可能泄露了;

不能读取到payload: 消息体直接被篡改,secret key和salt应该仍然安全。

以上内容写成一个函数,用于验证用户token。如果实现在python flask,可以考虑将此函数改为一个decorator修饰漆,将修饰器@到所有需要验证token的方法前面,则代码可以更加优雅。

# serializer for JWT

from itsdangerous import TimedJSONWebSignatureSerializer as Serializer

# exceptions for JWT

from itsdangerous import SignatureExpired, BadSignature, BadData

# Class xxx

def tokenAuth(token):

s = Serializer(

secret_key=api.app.config['SECRET_KEY'],

salt=api.app.config['AUTH_SALT'])

try:

data = s.loads(token)

except SignatureExpired:

msg = 'token expired'

app.logger.warning(msg)

return [None, None, msg]

except BadSignature, e:

encoded_payload = e.payload

if encoded_payload is not None:

try:

s.load_payload(encoded_payload)

except BadData:

msg = 'token tampered'

app.logger.warning(msg)

return [None, None, msg]

msg = 'badSignature of token'

app.logger.warning(msg)

return [None, None, msg]

except:

msg = 'wrong token with unknown reason'

app.logger.warning(msg)

return [None, None, msg]

if ('user_id' not in data) or ('user_role' not in data):

msg = 'illegal payload inside'

app.logger.warning(msg)

return [None, None, msg]

msg = 'user(' + data['user_id'] + ') logged in by token.'

userId = data['user_id']

roleId = data['user_role']

return [userId, roleId, msg]

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

# serializer for JWT

fromitsdangerousimportTimedJSONWebSignatureSerializerasSerializer

# exceptions for JWT

fromitsdangerousimportSignatureExpired,BadSignature,BadData

# Class xxx

deftokenAuth(token):

s=Serializer(

secret_key=api.app.config['SECRET_KEY'],

salt=api.app.config['AUTH_SALT'])

try:

data=s.loads(token)

exceptSignatureExpired:

msg='token expired'

app.logger.warning(msg)

return[None,None,msg]

exceptBadSignature,e:

encoded_payload=e.payload

ifencoded_payloadisnotNone:

try:

s.load_payload(encoded_payload)

exceptBadData:

msg='token tampered'

app.logger.warning(msg)

return[None,None,msg]

msg='badSignature of token'

app.logger.warning(msg)

return[None,None,msg]

except:

msg='wrong token with unknown reason'

app.logger.warning(msg)

return[None,None,msg]

if('user_id'notindata)or('user_role'notindata):

msg='illegal payload inside'

app.logger.warning(msg)

return[None,None,msg]

msg='user('+data['user_id']+') logged in by token.'

userId=data['user_id']

roleId=data['user_role']

return[userId,roleId,msg]

原文来自微信公众号:DevOps视角

本文链接:http://www.yunweipai.com/13797.html

python token_Python实现JWT(JSON Web Token)认证相关推荐

  1. sau交流学习社区-songEagle开发系列:Vue + Vuex + Koa 中使用JWT(JSON Web Token)认证

    一.前言 JWT(JSON Web Token),是为了在网络环境间传递声明而执行的一种基于JSON的开放标准(RFC 7519). JWT不是一个新鲜的东西,网上相关的介绍已经非常多了.不是很了解的 ...

  2. 在吗?认识一下JWT(JSON Web Token) ?

    点击上方"方志朋",选择"设为星标" 回复"666"获取新整理的面试文章 作者:是虎子呀  地址:my.oschina.net/u/4062 ...

  3. jwt如何防止token被窃取_在吗?认识一下JWT(JSON Web Token)?

    什么是JSON Web Token ? 官网介绍: JSON Web Token(JWT)是一个开放标准(RFC 7519),它定义了一种紧凑且自包含的方式,用于在各方之间安全地将信息作为JSON对象 ...

  4. JWT(JSON web token)

    1.什么是JWT JSON Web Token (JWT) is an open standard (RFC 7519) that defines a compact and self-contain ...

  5. 关于JWT(Json Web Token)的思考及使用心得

    什么是JWT? JWT(Json Web Token)是一个开放的数据交换验证标准rfc7519(php 后端实现JWT认证方法一般用来做轻量级的API鉴权.由于许多API接口设计是遵循无状态的(比如 ...

  6. 什么是 JWT -- JSON WEB TOKEN

    什么是JWT Json web token (JWT), 是为了在网络应用环境间传递声明而执行的一种基于JSON的开放标准((RFC 7519).该token被设计为紧凑且安全的,特别适用于分布式站点 ...

  7. JWT(JSON Web Token)简介及实现

    JWT(JSON Web Token):是一个开放标准(RFC 7519),它定义了一种紧凑且自包含的方式,用于在各方之间作为Json对象安全地传输信息.由于此信息是经过数字签名的,因此可以被验证和信 ...

  8. JWT (Json Web Token)教程

    JWT(Json Web Token)是实现token技术的一种解决方案,JWT由三部分组成: header(头).payload(载体).signature(签名). 头 JWT第一部分是heade ...

  9. jwt token 过期刷新_如何在SpringBoot中集成JWT(JSON Web Token)鉴权

    这篇博客主要是简单介绍了一下什么是JWT,以及如何在Spring Boot项目中使用JWT(JSON Web Token). 1.关于JWT 1.1 什么是JWT 老生常谈的开头,我们要用这样一种工具 ...

  10. 关于JWT(Json Web Token)的思考及使用心得 1

    什么是JWT? JWT(Json Web Token)是一个开放的数据交换验证标准rfc7519(https://tools.ietf.org/html/r...,一般用来做轻量级的API鉴权.由于许 ...

最新文章

  1. 洛谷 P2114 [NOI2014]起床困难综合症 解题报告
  2. python eval()函数使用
  3. asp.net 的page 基类页面 做一些判断 可以定义一个基类页面 继承Page类 然后重写OnPreLoad事件...
  4. 前端学习(1368):app.use使用
  5. OSS在线迁移服务剖析
  6. WordPress 博客平台
  7. Leetcode PHP题解--D56 637. Average of Levels in Binary Tree
  8. 在WPF TreeView中使用复选框
  9. Google叫停出售刷脸监控技术,只因目前无法避免被滥用
  10. 用python开启相机_使用“打开”编辑相机设置
  11. Unity项目中的资源管理
  12. python周报第十九周
  13. Android 防止button多次点击总结
  14. 为什么选择STM32-M3
  15. 【甲级PAT】-1132 Cut Integer (20分)-数字处理
  16. C#基础面试题(附答案)
  17. 高压蒸汽灭菌及验证相关知识
  18. ucos 和uclinux的区别及各自的特点
  19. 修改Arduino IDE背景和字体颜色
  20. 解决error: inlining failed in call to always_inline ‘int _mm_popcnt_u32(unsigned int)’

热门文章

  1. C/C++ 创建两个链表,实现两个链表高位到低位相加,并输出链表
  2. Android MediaPlayer 实现音乐播放器
  3. rk399_android7.1的mipi驱动代码追踪(部分)
  4. python学习之小说爬虫
  5. [HDU2294]Pendant
  6. 51nod 1105 第K大的数 【双重二分/二分套二分/两数组任意乘积后第K大数】
  7. 题解 AT25 【プログラミングコンテスト】
  8. 《深入理解计算机系统》速读提问
  9. ASP.Net Web API 的参数绑定[翻译]
  10. 设置多行的Table高度为100%,并在最后一行中加入iframe