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 相关文章推荐
在Python中处理XML的教程
Apr 29 Python
Python删除空文件和空文件夹的方法
Jul 14 Python
python3使用PyMysql连接mysql数据库实例
Feb 07 Python
python队列通信:rabbitMQ的使用(实例讲解)
Dec 22 Python
浅谈python脚本设置运行参数的方法
Dec 03 Python
Python数据集切分实例
Dec 08 Python
Python求离散序列导数的示例
Jul 10 Python
pyinstaller还原python代码过程图解
Jan 08 Python
Python基于class()实现面向对象原理详解
Mar 26 Python
Jupyter Notebook的连接密码 token查询方式
Apr 21 Python
PyCharm 2020.2 安装详细教程
Sep 25 Python
python字符串拼接.join()和拆分.split()详解
Nov 23 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
PHP会话处理的10个函数
2015/08/11 PHP
PHP获取指定时间段之间的 年,月,天,时,分,秒
2016/06/05 PHP
php实现与python进行socket通信的方法示例
2017/08/30 PHP
浅析php如何实现爬取数据原理
2018/09/27 PHP
PHP7.0连接DB操作实例分析【基于mysqli】
2019/09/26 PHP
Google Map Api和GOOGLE Search Api整合实现代码
2009/07/18 Javascript
监控 url fragment变化的js代码
2010/04/19 Javascript
js 获取计算后的样式写法及注意事项
2013/02/25 Javascript
js模拟select下拉菜单控件的代码
2013/05/08 Javascript
jQuery ReferenceError: $ is not defined 错误的处理办法
2013/05/10 Javascript
为jquery的ajaxfileupload增加附加参数的方法
2014/03/04 Javascript
jQuery实用技巧必备(中)
2015/11/03 Javascript
精通JavaScript的this关键字
2020/05/28 Javascript
JS button按钮实现submit按钮提交效果
2016/11/01 Javascript
详解JavaScript中的属性和特性
2016/12/08 Javascript
js调用刷新界面的几种方式
2017/05/03 Javascript
浅谈Node 调试工具入门教程
2018/03/20 Javascript
基于vue-ssr的静态网站生成器VuePress 初体验
2018/04/17 Javascript
详解Node.js中path模块的resolve()和join()方法的区别
2018/10/29 Javascript
详解Webpack如何引入CDN链接来优化编译后的体积
2019/06/21 Javascript
基于JavaScript伪随机正态分布代码实例
2019/11/07 Javascript
原生js实现html手机端城市列表索引选择城市
2020/06/24 Javascript
JavaScript ES 模块的使用
2020/11/12 Javascript
[48:00]完美世界DOTA2联赛循环赛 Forest vs Inki BO2第二场 11.04
2020/11/04 DOTA
jupyter安装小结
2016/03/13 Python
Python/ArcPy遍历指定目录中的MDB文件方法
2018/10/27 Python
解决python彩色螺旋线绘制引发的问题
2019/11/23 Python
ffmpeg+Python实现B站MP4格式音频与视频的合并示例代码
2020/10/21 Python
CSS3下的渐变文字效果实现示例
2018/03/02 HTML / CSS
CSS3实现彩色进度条动画的示例
2020/10/29 HTML / CSS
Tripadvisor新西兰:阅读评论,比较价格和酒店预订
2018/02/10 全球购物
CheapTickets泰国:廉价航班,查看促销价格并预订机票
2019/12/28 全球购物
艺术设计专业个人求职信范文
2013/12/11 职场文书
预备党员思想汇报
2014/01/08 职场文书
作息时间调整通知
2015/04/22 职场文书
vue项目proxyTable配置和部署服务器
2022/04/14 Vue.js