Sanic 是基于 Python 的一个支持高并发的异步 web 框架,sanic-jwt 则是针对Sanic 开发的一个基于 PyJWT 封装的 JWT 授权认证模块。

sanic-jwt

安装

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 的使用的更多相关文章

  1. python实现JWT

    python实现JWT 一.常见的几种实现认证的方法 1.1basic auth 1.2cookie 1.3token json web token--一种基于token的json格式web认证方法. ...

  2. 理解JWT(JSON Web Token)认证及python实践

    原文:https://segmentfault.com/a/1190000010312468?utm_source=tag-newest 几种常用的认证机制 HTTP Basic Auth HTTP ...

  3. 理解JWT(JSON Web Token)认证

    理解JWT(JSON Web Token)认证 最近想做个小程序,需要用到授权认证流程.以前项目都是用的 OAuth2 认证,但是Sanic 使用OAuth2 不太方便,就想试一下 JWT 的认证方式 ...

  4. 微信小程序开发:python+sanic 实现小程序登录注册

    开发微信小程序时,接入小程序的授权登录可以快速实现用户注册登录的步骤,是快速建立用户体系的重要一步.这篇文章将介绍 python + sanic + 微信小程序实现用户快速注册登录全栈方案. 微信小程 ...

  5. 看图理解JWT如何用于单点登录

    单点登录是我比较喜欢的一个技术解决方案,一方面他能够提高产品使用的便利性,另一方面他分离了各个应用都需要的登录服务,对性能以及工作量都有好处.自从上次研究过JWT如何应用于会话管理,加之以前的项目中也 ...

  6. JWT实现token-based会话管理

    上文<3种web会话管理的方式>介绍了3种会话管理的方式,其中token-based的方式有必要从实现层面了解一下.本文主要介绍这方面的内容.上文提到token-based的实现目前有一个 ...

  7. 用JWT来保护我们的ASP.NET Core Web API

    在上一篇博客中,自己动手写了一个Middleware来处理API的授权验证,现在就采用另外一种方式来处理这个授权验证的问题,毕竟现在也 有不少开源的东西可以用,今天用的是JWT. 什么是JWT呢?JW ...

  8. Laravel-lumen 配置JWT

    具体步骤参照: [ JWT & Lumen ] 第一步 在项目根目录 执行命令 composer require tymon/jwt-auth第二步 在 bootstrap/app.php 的 ...

  9. .net core Jwt 添加

    Jwt 已经成为跨平台身份验证通用方案,如不了解请关注:https://jwt.io/. 为了和微软其他验证模块有个比较好的衔接,项目中采用了微软开发的jwt组件: System.IdentityMo ...

随机推荐

  1. QQ空间自动点赞js代码

    1.jQuery().each(): each() 方法为每个匹配元素规定要运行的函数. 提示:返回 false 可用于及早停止循环. 函数原型: function(index,element) 为每 ...

  2. K8S(14)监控实战-grafana出图_alert告警

    k8s监控实战-grafana出图_alert告警 目录 k8s监控实战-grafana出图_alert告警 1 使用炫酷的grafana出图 1.1 部署grafana 1.1.1 准备镜像 1.1 ...

  3. Cobbler自定义安装系统和私有源

    1.自定义安装系统(根据mac地址) --name=定义名称 --mac=客户端的mac地址 --ip-address=需求的ip --subnet=掩码 --gateway=网关 --interfa ...

  4. boomworks 1999~2009

    大众软件 PC定时执行专家 4.0 (PCTaskTimer) - 功能强大.简单易用的定时执行软件.具有功能多.体积小.消耗资源少的特点. 超级网际搜索(SuperSearch) - 免费.快速.高 ...

  5. bnuoj-53073 萌萌哒身高差 【数学】【非原创】

    "清明时节雨纷纷,路上行人欲断魂." 然而wfy同学的心情是愉快的,因为BNU ACM队出去春游啦!并且,嗯... 以下是wfy同学的日记: 昨天,何老师告诉我们:明天我们去春游, ...

  6. VuePress plugins All In One

    VuePress plugins All In One VuePress & element-ui & docs $ yarn add -D vuepress-plugin-demo- ...

  7. GPU 加速 & WebGL

    GPU 加速 & WebGL 开启 GPU 加速, 硬件加速 垃圾面试官,瞎忽悠 holy shit 美国想象力英语,前端 leader WebGL 加速 ??? 是什么鬼 ??? three ...

  8. CSS Layout All In One

    CSS Layout All In One CSS2 position float % px , rem, em CSS3 flex grid multi column vw / vh 常见布局模式 ...

  9. svg insert shape string bug

    svg insert shape string bug not support custom areaProps attributes ??? const svg = document.querySe ...

  10. springCloud服务流程

    springCloud的服务流程:消费者调用生产者 1.通过接口化的请求调用(指定接口的服务名字和服务地址)只是做定义,并没有真正做到. 2.Feign组件,远程去注册中心找到服务的名字和服务的地址然 ...