flask 实现token机制的示例代码


Posted in Python onNovember 07, 2019

token 的生成

用token校验身份,是前后端交互的常用方式。

它有以下特性:

  • 会失效
  • 加密
  • 可以根据它拿到用户的信息

生成方式( 内部配置的私钥+有效期+用户的id )

#导入依赖包
from flask import request,jsonify,current_app
from itsdangerous import TimedJSONWebSignatureSerializer as Serializer

def create_token(api_user):
  '''
  生成token
  :param api_user:用户id
  :return: token
  '''
  
  #第一个参数是内部的私钥,这里写在共用的配置信息里了,如果只是测试可以写死
  #第二个参数是有效期(秒)
  s = Serializer(current_app.config["SECRET_KEY"],expires_in=3600)
  #接收用户id转换与编码
  token = s.dumps({"id":api_user}).decode("ascii")
  return token

token的校验

校验接收到的token,如果成功返回用户信息,否则返回None

#基于上面的基础再导入用户的模型类
from app.model import User

def verify_token(token):
  '''
  校验token
  :param token: 
  :return: 用户信息 or None
  '''
  
  #参数为私有秘钥,跟上面方法的秘钥保持一致
  s = Serializer(current_app.config["SECRET_KEY"])
  try:
    #转换为字典
    data = s.loads(token)
  except Exception:
    return None
  #拿到转换后的数据,根据模型类去数据库查询用户信息
  user = User.query.get(data["id"])
  return user

用装饰器写一个必须携带token的校验

有很多接口是必须登录才能操作的,最好的方式就是在写一个装饰器,添加在需要的api上

#在上面的基础上导入
import functools

def login_required(view_func):
  @functools.wraps(view_func)
  def verify_token(*args,**kwargs):
    try:
      #在请求头上拿到token
      token = request.headers["z-token"]
    except Exception:
      #没接收的到token,给前端抛出错误
      #这里的code推荐写一个文件统一管理。这里为了看着直观就先写死了。
      return jsonify(code = 4103,msg = '缺少参数token')
    
    s = Serializer(current_app.config["SECRET_KEY"])
    try:
      s.loads(token)
    except Exception:
      return jsonify(code = 4101,msg = "登录已过期")

    return view_func(*args,**kwargs)

  return verify_token

使用案例

生成token(案例)

#此处的api是蓝图的对象
from . import api
from app.model import User,db
from flask import request,jsonify
#导入刚刚写的文件方法
from app.utils.common import create_token,login_required,verify_token

@api.route("/login",methods=["POST"])
def login():
  '''
  用户登录
  :return:token
  '''
  res_dir = request.get_json()
  if res_dir is None:
    #这里的code,依然推荐用一个文件管理状态
    return jsonify(code = 4103,msg = "未接收到参数")
  
  #获取前端传过来的参数
  phone = res_dir.get("phone")
  password = res_dir.get("password")
  
  #校验参数
  if not all([phone,password]):
    return jsonify(code=4103, msg="请填写手机号或密码")

  if not re.match(r"1[23456789]\d{9}",phone):
    return jsonify(code=4103,msg="手机号有误")

  try:
    user = User.query.filter_by(phone=phone).first()
  except Exception:
    return jsonify(code=4004,msg="获取信息失败")

  if user is None or not user.check_password(password):
    return jsonify(code=4103,msg="手机号或密码错误")
  
  #获取用户id,传入生成token的方法,并接收返回的token
  token = create_token(user.id)
  
  #把token返回给前端
  return jsonify(code=0,msg="成功",data=token)

必须登录的校验与根据token拿到用户信息(案例)

@api.route("/user/detail")
@login_required #必须登录的装饰器校验
def userInfo():
  '''
  用户信息
  :return:data
  '''
  token = request.headers["z-token"]
  #拿到token,去换取用户信息
  user = verify_token(token)

  data = {
    "phone":user.phone,
    "name":user.name,
    "head_portrait":user.head_portrait,
    "intro":user.intro,
    "level":user.level
  }

  return jsonify(code=0,msg="成功",data=data)

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持三水点靠木。

Python 相关文章推荐
Django中cookie的基本使用方法示例
Feb 03 Python
Python检测网络延迟的代码
May 15 Python
python跳过第一行快速读取文件内容的实例
Jul 12 Python
python 获取sqlite3数据库的表名和表字段名的实例
Jul 17 Python
python将print输出的信息保留到日志文件中
Sep 27 Python
浅谈Python type的使用
Nov 19 Python
python模拟预测一下新型冠状病毒肺炎的数据
Feb 01 Python
python实现井字棋小游戏
Mar 04 Python
150行python代码实现贪吃蛇游戏
Apr 24 Python
Python pandas 列转行操作详解(类似hive中explode方法)
May 18 Python
python中pandas对多列进行分组统计的实现
Jun 18 Python
Pytest中skip skipif跳过用例详解
Jun 30 Python
python3反转字符串的3种方法(小结)
Nov 07 #Python
Python中__repr__和__str__区别详解
Nov 07 #Python
Python通过Manager方式实现多个无关联进程共享数据的实现
Nov 07 #Python
Python上下文管理器类和上下文管理器装饰器contextmanager用法实例分析
Nov 07 #Python
Python中xml和dict格式转换的示例代码
Nov 07 #Python
python对象转字典的两种实现方式示例
Nov 07 #Python
python多线程高级锁condition简单用法示例
Nov 07 #Python
You might like
默默简单的写了一个模板引擎
2007/01/02 PHP
PHP url的pathinfo模式加载不同控制器的简单实现
2016/08/12 PHP
php使用环形链表解决约瑟夫问题完整示例
2018/08/07 PHP
tp5框架内使用tp3.2分页的方法分析
2019/05/05 PHP
Thinkphp5.0 框架的请求方式与响应方式分析
2019/10/14 PHP
php5.3/5.4/5.5/5.6/7常见新增特性汇总整理
2020/02/27 PHP
创建公共调用 jQuery Ajax 带返回值
2012/08/01 Javascript
Jquery实现网页跳转或用命令打开指定网页的解决方法
2013/07/09 Javascript
IE中JS跳转丢失referrer问题的2个解决方法
2014/07/18 Javascript
jQuery性能优化技巧分析
2015/02/20 Javascript
如何实现chrome浏览器关闭页面时弹出“确定要离开此面吗?”
2015/03/05 Javascript
JavaScript实现大图轮播效果
2017/01/11 Javascript
Vue.js中extend选项和delimiters选项的比较
2017/07/17 Javascript
JS switch判断 三目运算 while 及 属性操作代码
2017/09/03 Javascript
JavaScript实现快速排序的方法分析
2018/01/10 Javascript
Bootstrap实现可折叠分组侧边导航菜单
2018/03/07 Javascript
vuejs项目打包之后的首屏加载优化及打包之后出现的问题
2018/04/01 Javascript
解决vue.js 数据渲染成功仍报错的问题
2018/08/25 Javascript
JS计算斐波拉切代码实例
2019/09/12 Javascript
python3访问sina首页中文的处理方法
2014/02/24 Python
python获取本地计算机名字的方法
2015/04/29 Python
pandas 数据归一化以及行删除例程的方法
2018/11/10 Python
Python3中configparser模块读写ini文件并解析配置的用法详解
2020/02/18 Python
Python post请求实现代码实例
2020/02/28 Python
Python figure参数及subplot子图绘制代码
2020/04/18 Python
Django windows使用Apache实现部署流程解析
2020/10/12 Python
X/HTML5 和 XHTML2
2008/10/17 HTML / CSS
通过HTML5 Canvas API绘制弧线和圆形的教程
2016/03/14 HTML / CSS
Oracle里面常用的数据字典有哪些
2014/02/14 面试题
运动会广播稿300字
2014/01/10 职场文书
客户答谢会致辞
2015/07/30 职场文书
幼儿园心得体会范文
2016/01/21 职场文书
导游词之山东红叶谷
2019/10/31 职场文书
聊聊pytorch测试的时候为何要加上model.eval()
2021/05/23 Python
Java 使用类型为Object的变量指向任意类型的对象
2022/04/13 Java/Android