sanic-jwt 的使用
Sanic 是基于 Python 的一个支持高并发的异步 web 框架,sanic-jwt 则是针对Sanic 开发的一个基于 PyJWT 封装的 JWT 授权认证模块。
sanic-jwt
- 项目主页:https://github.com/ahopkins/sanic-jwt
- 官方文档:https://sanic-jwt.readthedocs.io/en/latest/index.html
安装
pip install sanic-jwt
实例
下面实例主要总结:
- 常用参数的配置;
- 修改发生异常时返回的响应数据;
- 解析和修改payload;
- 查找用户;
from sanic import Sanic, request, response
from sanic_jwt import initialize, Configuration, Responses, protected, exceptions, Authentication, inject_user class User: def __init__(self, uid, username, sex, password, info, black_level=0):
self.user_id = uid
self.sex = sex
self.username = username
self.password = password
self.personal_info = info # 只能登录后个人可见的信息
self.black_level = black_level # 黑名单等级,默认0为正常用户 def __repr__(self):
return "User(id='{}')".format(self.user_id) def to_dict(self): return {
"uid": self.user_id, # 注意:此处 "uid" 要与 MyJWTConfig 中的 user_id 设置一致!
"sex": self.sex,
"username": self.username,
"personal_info": self.personal_info
} # 模拟一个用户列表
users = [
User(1, "user1", "男", "123", "这是仅 user1 可见信息", 1),
User(2, "user2", "女", "456", "这是仅 user2 可见信息", 0)
] username_table = {u.username: u for u in users}
userid_table = {u.user_id: u for u in users} async def authenticate(req: request.Request):
username = req.json.get("username", None)
password = req.json.get("password", None) if not username or not password:
raise exceptions.AuthenticationFailed("用户名或密码为空!")
user = username_table.get(username, None)
if user is None:
raise exceptions.AuthenticationFailed("用户名或密码不正确!")
if password != user.password:
raise exceptions.AuthenticationFailed("用户名或密码不正确!")
return user class MyJWTConfig(Configuration):
# -------------- url_prefix ---------------------
# [描述] 获取授权的路由地址
# [默认] '/auth'
url_prefix = '/login' # -------------- secret -------------------------
# [描述] 加密密码
# [默认] 'This is a big secret. Shhhhh'
# [建议] 该密码是 JWT 的安全核心所在,需要保密,尽量使用更长更复杂的密码
secret = ',$FCyFZ^b16#m:ragM#d-!;4!U5zgZDF(EhswOL_HGV#xN1Ll%MaBU42AN=jXgp7' # -------------- expiration_delta ----------------------
# [描述] 过期时间,单位为秒
# [默认] 30 分钟,即:60 * 30
# [建议] 该时间不宜过长,同时建议开启 refresh_token_enabled 以便自动更新 token
expiration_delta = 60 * 60 # 改为 10 分钟过期 # -------------- cookie_set ---------------------
# [描述] 是否将获取到的 token 信息写入到 cookie
# [默认] False,即不写入cookie
# 只有该项为 True,其它 cookie 相关设置才会起效。
# cookie_set = True # -------------- cookie_access_token_name ---------------
# [描述] cookie 中存储 token 的名称。
# [默认] 'access_token'
# cookie_access_token_name = "token" # -------------- cookie_access_token_name ---------------
# [描述] 包含用户 id 的用户对象的键或属性,这里对应 User 类的用户唯一标识
# [默认] 'user_id'
user_id = "uid" claim_iat = True # 显示签发时间,JWT的默认保留字段,在 sanic-jwt 中默认不显示该项 class MyJWTAuthentication(Authentication): # 从 payload 中解析用户信息,然后返回查找到的用户
# args[0]: request
# args[1]: payload
async def retrieve_user(self, *args, **kwargs):
user_id_attribute = self.config.user_id()
if not args or len(args) < 2 or user_id_attribute not in args[1]:
return {}
user_id = dict(args[1]).get(user_id_attribute)
# TODO: 根据项目实际情况进行修改
user = userid_table.get(user_id)
return user # 拓展 payload
async def extend_payload(self, payload, *args, **kwargs):
# 可以获取 User 中的一些属性添加到 payload 中
# 注意:payload 信息是公开的,这里不要添加敏感信息
user_id_attribute = self.config.user_id()
user_id = payload.get(user_id_attribute)
# TODO: 根据项目实际情况进行修改
user: User = userid_table.get(user_id)
payload.update({'sex': user.sex}) # 比如添加性别属性
return payload async def extract_payload(self, req, verify=True, *args, **kwargs):
return await super().extract_payload(req, verify) class MyJWTResponse(Responses): # 自定义发生异常的返回数据
@staticmethod
def exception_response(req: request.Request, exception: exceptions):
# sanic-jwt.exceptions 下面定义的异常类型:
# AuthenticationFailed
# MissingAuthorizationHeader
# MissingAuthorizationCookie
# InvalidAuthorizationHeader
# MissingRegisteredClaim
# Unauthorized
msg = str(exception)
if exception.status_code == 500:
msg = str(exception)
elif isinstance(exception, exceptions.AuthenticationFailed):
msg = str(exception)
else:
if "expired" in msg:
msg = "授权已失效,请重新登录!"
else:
msg = "未授权,请先登录!"
result = {
"status": exception.status_code,
"data": None,
"msg": msg
}
return response.json(result, status=exception.status_code) app = Sanic("my_auth_app")
initialize(app, authenticate=authenticate,
authentication_class=MyJWTAuthentication, configuration_class=MyJWTConfig, responses_class=MyJWTResponse) @app.route("/index")
@protected() # 保护该路由,只有授权用户才能访问
async def protected_route_index(req: request.Request):
# 从 request 中获取 payload,然后返回给前端
payload = await req.app.auth.extract_payload(req)
return response.json({'payloadInfo': payload}) @app.route("/info")
@inject_user() # 注入用户信息
@protected() # 保护该路由,只有授权用户才能访问
async def protected_route_info(req: request.Request, user: User):
if user.black_level == 0:
return response.json({'userName': user.username, "personalInfo": user.personal_info})
else: # 进入黑名单等级之后限制查看
return response.json({'userName': user.username, "personalInfo": ""}) if __name__ == "__main__":
app.run(host="0.0.0.0", port=8080, auto_reload=True)
Configuration 参数
下面列出的参数可以根据需要在前面的 MyJWTConfig 这个类下进行添加设置。
参数 | 描述 | 默认 | 备注 |
access_token_name
|
标识访问令牌的key | 'access_token' | |
algorithm
|
生成标记的哈希算法 | 'HS256' 可选项: HS256, HS384, HS512, ES256, ES384, ES512, RS256, RS384, RS512, PS256, PS384, PS512 |
|
auth_mode
|
是否启用 /auth 接口 | True | |
authorization_header
|
HTTP请求 header 中令牌key | 'authorization' | |
authorization_header_prefix
|
HTTP请求header中JWT的前缀 | 'Bearer' | |
authorization_header_refresh_prefix
|
保留字,未使用 | 'Refresh' | |
claim_aud
|
面向的用户 | None | |
claim_iat
|
是否启用生成令牌签发时间 | False | |
claim_iss
|
令牌签发者 | None | |
claim_nbf
|
是否 启用生成令牌在签发后多久生效 功能 | False | |
claim_nbf_delta
|
令牌在签发后多久生效 | 60 * 3,即:3 分钟 | |
cookie_access_token_name
|
使用cookie令牌时,cookie中令牌的名称 | 'access_token' | |
cookie_domain
|
cookie所在的域 | '' | |
cookie_httponly
|
是否启用 http only cookie | True | |
cookie_refresh_token_name
|
使用cookie令牌,cookie中刷新令牌的名称 | 'refresh_token' | |
cookie_set
|
启用cookie令牌 | False | |
cookie_strict
|
启用cookie令牌,cookie获取失败后是否禁用头部令牌 | False | |
cookie_token_name
|
cookie_access_token_name 的别名,用于测试 | False | 实测该值无效,应使用 cookie_access_token_name |
do_protection
|
启用@protected装饰器正常工作 | True | |
expiration_delta
|
令牌有效期 | 60 * 5 * 6(30分钟) | |
generate_refresh_token
|
创建和返回刷新令牌的方法 | sanic_jwt.utils.generate_refresh_token | |
leeway
|
系统时间配置中微小更改的回旋时间秒 | 60 * 3(3分钟) | |
path_to_authenticate
|
身份验证接口路径 | '/' | |
path_to_refresh
|
刷新令牌接口路径 | '/refresh' | |
path_to_retrieve_user
|
当前用户接口路径 | '/me' | |
path_to_verify
|
令牌验证接口 | '/verify' | |
private_key
|
用于生成令牌的私钥,依赖于使用的散列算法 | None | |
public_key
|
secret的别名 | ||
query_string_access_token_name
|
查询字符串令牌,cookie中令牌的名称 | 'access_token' | |
query_string_refresh_token_name
|
查询字符串令牌,cookie中刷新令牌的名称 | 'refresh_token' | |
query_string_set
|
开启查询字符串令牌 | False | |
query_string_strict
|
开启查询字符串令牌,查询字符串不存在是否禁用头部令牌 | False | |
refresh_token_enabled
|
启用刷新令牌 | False | 如果开启,就需要存储refresh_token, 所以需要额外代码实现。 |
refresh_token_name
|
刷新令牌的key | 'refresh_token' | |
scopes_enabled
|
启用scope块并将作用域添加到jwt payload | False | |
scopes_name
|
jwt payload中scope的key | 'scopes' | |
secret
|
用于哈希算法生成和签名JWT,每个应用应该设置自已的值 |
'This is a big secret. Shhhhh' |
|
strict_slashes
|
启用对接口url执行严格的/匹配 | False | |
url_prefix
|
sanic jwt默认接口的前缀 | '/auth' | |
user_id
|
包含用户 id 的用户对象的键或属性 | 'user_id' | |
verify_exp | 开启令牌过期验证 | True | |
参考:
sanic-jwt
https://blog.csdn.net/zhouping118/article/details/88736986
sanic-jwt 的使用的更多相关文章
- python实现JWT
python实现JWT 一.常见的几种实现认证的方法 1.1basic auth 1.2cookie 1.3token json web token--一种基于token的json格式web认证方法. ...
- 理解JWT(JSON Web Token)认证及python实践
原文:https://segmentfault.com/a/1190000010312468?utm_source=tag-newest 几种常用的认证机制 HTTP Basic Auth HTTP ...
- 理解JWT(JSON Web Token)认证
理解JWT(JSON Web Token)认证 最近想做个小程序,需要用到授权认证流程.以前项目都是用的 OAuth2 认证,但是Sanic 使用OAuth2 不太方便,就想试一下 JWT 的认证方式 ...
- 微信小程序开发:python+sanic 实现小程序登录注册
开发微信小程序时,接入小程序的授权登录可以快速实现用户注册登录的步骤,是快速建立用户体系的重要一步.这篇文章将介绍 python + sanic + 微信小程序实现用户快速注册登录全栈方案. 微信小程 ...
- 看图理解JWT如何用于单点登录
单点登录是我比较喜欢的一个技术解决方案,一方面他能够提高产品使用的便利性,另一方面他分离了各个应用都需要的登录服务,对性能以及工作量都有好处.自从上次研究过JWT如何应用于会话管理,加之以前的项目中也 ...
- JWT实现token-based会话管理
上文<3种web会话管理的方式>介绍了3种会话管理的方式,其中token-based的方式有必要从实现层面了解一下.本文主要介绍这方面的内容.上文提到token-based的实现目前有一个 ...
- 用JWT来保护我们的ASP.NET Core Web API
在上一篇博客中,自己动手写了一个Middleware来处理API的授权验证,现在就采用另外一种方式来处理这个授权验证的问题,毕竟现在也 有不少开源的东西可以用,今天用的是JWT. 什么是JWT呢?JW ...
- Laravel-lumen 配置JWT
具体步骤参照: [ JWT & Lumen ] 第一步 在项目根目录 执行命令 composer require tymon/jwt-auth第二步 在 bootstrap/app.php 的 ...
- .net core Jwt 添加
Jwt 已经成为跨平台身份验证通用方案,如不了解请关注:https://jwt.io/. 为了和微软其他验证模块有个比较好的衔接,项目中采用了微软开发的jwt组件: System.IdentityMo ...
随机推荐
- Codeforces Round #603 C. Everyone is a Winner!
题意:给你一个整数n,求所有n/k的值(k∈{1,2,3...,n,.......}). 题解:最简单的方法是用枚举1~sqrt(n),把除数和商放进set中,就能直接水过,但后来看其他人的题解了解到 ...
- word2vector代码实践
引子 在上次的 <word2vector论文笔记>中大致介绍了两种词向量训练方法的原理及优劣,这篇咱们以skip-gram算法为例来代码实践一把. 当前教程参考:A Word2Vec Ke ...
- Zabbix 监控 SNMP & JMX
Zabbix 配置清华源 # 安装清华源 yum 仓库 [root@db01 ~]# rpm -ivh https://mirrors.tuna.tsinghua.edu.cn/zabbix/zabb ...
- 二进制安装kubernetes(二) kube-apiserver组件安装
根据架构图,我们的apiserver部署在hdss7-21和hdss7-22上: 首先在hdss7-200上申请证书并拷贝到21和22上: 创建证书文件: # cd /opt/certs # vi c ...
- WSL (Windows Subsystem for Linux) 的 VSLAM (Visual Simultaneous Localization and Mapping) 道路
WSL 的 VSLAM 道路 以 Windows Subsystem for Linux 闯入 Visual Simultaneous Localization and Mapping 世界的艰难道路 ...
- 缓冲区溢出实验 4 内存管理(类似于malloc free)
实验环境.代码.及准备 https://www.cnblogs.com/lqerio/p/12870834.html vul4 观察foo函数,可见问题在于最后一次tfree(q).由于之前已经tfr ...
- git命令简写配置
在使用git工具时,有些命令比较常用,为了加快输入速度,可以自定义一些简写配置,如下所示: git st # git status git ci # git commit git br # git b ...
- Verilog基础语法总结
去年小学期写的,push到博客上好了 Verilog 的基本声明类型 wire w1; // 线路类型 reg [-3:4] r1; // 八位寄存器 integer mem[0:2047]; // ...
- JavaScript中的对象引用和复制
在JavaScript分为两种原始值和引用值类型,原始值之间的复制是值对值得复制,而引用类型则是引用对引用的复制: // 原始值的复制: let num1 = 1; let num2 = num1; ...
- OpenCV3.2+Python3.5+Ubuntu16.04+缺少boostdesc和vgg_generated
问题: OpenCV3.2在cmake通过https无法获取boostdesc和vgg_generated2类文件 可尝试的解决方法: 参考, 依其方法至这里做调整, 最后注释xfeatures2d/ ...