最安全的api接口认证

实现步骤:

1、客户端与服务器都存放着用于验证的Token字段,客户端在本地把自己的 用户名+时间戳+Token 组合进行MD5加密后生成一段新的md5-token。

2、客户端访问的时候携带:用户名、时间戳、md5-token。

3、服务端收到请求后,先判断用户名、时间戳是否合法、假设先判断发送过来的时间戳和现在的时间戳不能大于2分钟。

4、如果是在2分钟之内,到redis里查看有没有该用户为key对应的md5-token,并判断它和发送过来的md5-token是否相同,如果有相同,说明该md5-token已经请求过,不能在操作,如果没找到相同的md5-token,说明是第一次请求,把用户名为key,md5-token为vallue存入redis,存在时间设为2分钟。

5、如果以上都通过了,在去数据库取出用户名和Token字段像客户端一样的方式进行加密。对比两个加密字段,相同则通过验证。

1、例如我们在请求的url后带上 用户名+时间戳+加密的Token

客户端

#!/usr/bin/env python
# -*- coding:utf-8 -*-
import os
BaseDir = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) Params = {
"server": "127.0.0.1",
"port":8000,
'request_timeout':30,
"urls":{
"asset_report_no_id":"/asset/asset_report_no_id/",
"asset_report":"/asset/asset_report/",
},
'asset_id_path':'%s/var/.asset_id' % BaseDir,
'log_file': '%s/logs/run_log' % BaseDir,
'auth':{
'user':'123456789@qq.com',
'token': 'abc'
},
}
url=http://127.0.0.1:8000/asset/
import hashlib,time
def get_token(username,token_id):
timestamp = int(time.time())
md5_format_str = "%s\n%s\n%s" %(username,timestamp,token_id)
obj = hashlib.md5()
obj.update(md5_format_str)
print "token format:[%s]" % md5_format_str
print "token :[%s]" % obj.hexdigest()
return obj.hexdigest()[10:17], timestamp
def attach_token(url_str):
'''生成一个加密验证在url后'''
user = settings.Params['auth']['user']
token_id = settings.Params['auth']['token'] md5_token,timestamp = get_token(user,token_id)
url_arg_str = "user=%s&timestamp=%s&token=%s" %(user,timestamp,md5_token)
if "?" in url_str:
new_url = url_str + "&" + url_arg_str
else:
new_url = url_str + "?" + url_arg_str
return new_url #生成一个带着加密token的url
url = attach_token(url)

发送请求

data_encode = urllib.urlencode(asset_data)#asset_data为要发送的数据
req = urllib2.Request(url=url,data=data_encode)
res_data = urllib2.urlopen(req,timeout=settings.Params['request_timeout'])
callback = res_data.read()
callback = json.loads(callback)
print (callback)

服务端

2、我们给服务端写一个装饰器token_required,用来验证

#!/usr/bin/env python
# -*- coding:utf-8 -*-
import time,hashlib,json
from asset import models
from django.shortcuts import render,HttpResponse
from cmdb import settings
from django.core.exceptions import ObjectDoesNotExist def gen_token(username,timestamp,token):
token_format = "%s\n%s\n%s" %(username,timestamp,token)
obj = hashlib.md5()
obj.update(token_format)
return obj.hexdigest()[10:17] def token_required(func):
def wrapper(*args,**kwargs):
response = {"errors":[]}
get_args = args[0].GET
username = get_args.get("user")
token_md5_from_client = get_args.get("token")
timestamp = get_args.get("timestamp") if not username or not timestamp or not token_md5_from_client:
response['errors'].append({"auth_failed":"This api requires token authentication!"})
return HttpResponse(json.dumps(response))
try:
if abs(time.time() - int(timestamp)) > settings.TOKEN_TIMEOUT:#验证时间有没有超过2分钟
response['errors'].append({"auth_failed":"The token is expired!"})
else:
'''如果没超过两分钟,检查redis里有没有这个加密token'''
red_result = __redies_token(username,token_md5_from_client)
if red_result: #等于True说明是第一次请求,进入下一步验证
user_obj = models.MyUser.objects.get(email=username)
token_md5_from_server = gen_token(username,timestamp,user_obj.token)
if token_md5_from_client != token_md5_from_server:
response['errors'].append({"auth_failed":"Invalid username or token_id"})
else: print("通过验证")
else:
response['errors'].append({"auth_failed":"The token is expired!"}) print("\033[41;1m;%s ---client:%s\033[0m" %(time.time(),timestamp), time.time() - int(timestamp))
except ObjectDoesNotExist as e:
response['errors'].append({"auth_failed":"Invalid username or token_id"})
if response['errors']:
return HttpResponse(json.dumps(response))
else:
return func(*args,**kwargs)
return wrapper def __redies_token(username,token_md5_from_client):
import redis
r = redis.Redis(host='192.168.0.109', port=6379)
val = r.get(username)
if val == token_md5_from_client:
print("是以请求过的token")
return False
else:#不存在,则以用户名为key,加密的token为value存入缓存,存在时间2分钟
r.set(username, token_md5_from_client,ex=120)
return True

最安全的api接口认证的更多相关文章

  1. API接口认证

    restful API接口可以很方便的让其他系统调用,为了让指定的用户/系统可以调用开放的接口,一般需要对接口做认证; 接口认证有两种方式: 1.认证的token当做post/get的参数,serve ...

  2. spring boot 2 集成JWT实现api接口认证

    JSON Web Token(JWT)是目前流行的跨域身份验证解决方案.官网:https://jwt.io/本文使用spring boot 2 集成JWT实现api接口验证. 一.JWT的数据结构 J ...

  3. 每天一点点之laravel框架 - Laravel5.6 + Passport实现Api接口认证

    1.首先通过 Composer 包管理器安装 Passport: composer require laravel/passport 注:如果安装过程中提示需要更高版本的 Laravel:larave ...

  4. python api接口认证脚本

    import requests import sys def acces_api_with_cookie(url_login, USERNAME, PASSWORD, url_access):     ...

  5. Django项目:CMDB(服务器硬件资产自动采集系统)--03--03CMDB信息安全API接口交互认证

    #settings.py """ Django settings for AutoCmdb project. Generated by 'django-admin sta ...

  6. 03: zabbix API接口 对 主机、主机组、模板、应用集、监控项、触发器等增删改查

    目录:Django其他篇 01: 安装zabbix server 02:zabbix-agent安装配置 及 web界面管理 03: zabbix API接口 对 主机.主机组.模板.应用集.监控项. ...

  7. api接口思路介绍

    现在很流行api了,但各种api做法不一样,下面我整理了一些自己的想法,也是看了各大门户网站开放的api应用想到的,与大家分享分享,高手跳过.   API(Application Programmin ...

  8. api接口对于客户端的身份认证方式以及安全措施

    转载 基于http协议的api接口对于客户端的身份认证方式以及安全措施 由于http是无状态的,所以正常情况下在浏览器浏览网页,服务器都是通过访问者的cookie(cookie中存储的jsession ...

  9. 使用Flask设计带认证token的RESTful API接口

    大数据时代 Just a record. 使用Flask设计带认证token的RESTful API接口[翻译] 上一篇文章, 使用python的Flask实现一个RESTful API服务器端  简 ...

随机推荐

  1. javascript、jquery 、C#、sqlserveer、mysql、oracle中字符串截取的区别和用法

    下标从0开始 ,并且包括起始位 javascript 中字符串截取 : substring(Number start,Number end) var substr = "liuguangfa ...

  2. hexo干货系列:(六)hexo提交搜索引擎(百度+谷歌)

    前言 能看到这里,说明大家都跟我一样,已经把博客搭起来并洋洋洒洒写了几篇博文,正春风得意感觉良好的时候,搭建博客有屎以来最大的危机出现在没有准备的我面前,百度+谷歌都无法搜索到我的博客.装逼还没几天就 ...

  3. POJ 2553 The Bottom of a Graph 【scc tarjan】

    图论之强连通复习开始- - 题目大意:给你一个有向图,要你求出这样的点集:从这个点出发能到达的点,一定能回到这个点 思路:强连通分量里的显然都可以互相到达 那就一起考虑,缩点后如果一个点有出边,一定不 ...

  4. BZOJ:[JSOI2009]游戏Game【二分图匹配乱搞】

    题目大意:n*m的棋盘,其中有些区域是禁区,两个人在棋盘上进行博弈,后手选择棋子的初始位置,然后先后手轮流将棋子往上下左右移动,走过的区域不能再走,问能否有一个位置使得后手必胜 Input 输入数据首 ...

  5. hdu 1565 状态压缩dp

    #include<stdio.h> #include<string.h> int Max(int a,int b) { return a>b?a:b; } int dp] ...

  6. android中的OnClickListener两种实现方式

    android的activity点击事件中,通过OnClickListener来实现,要实现点击事件有两种方式 1.通过定义一个OnClickListener的内部类来实现 The example b ...

  7. hdu 2438 Turn the corner [ 三分 ]

    传送门 Turn the corner Time Limit: 3000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Othe ...

  8. php的抽象类

    php的抽象类 //定义一个老虎类 abstract class Tiger{ public abstract function climb(); } //定义一个孟加拉虎类 class MTiger ...

  9. iOS React Native 环境的搭建

    react native 的官网:http://reactnative.cn/docs/0.47/getting-started.html#content  --iOS如何搭建mac版的环境 1.配置 ...

  10. python学习之-- random模块

    random模块random.random():随机打印一个小数random.randint(1,10):随机打印1-10之间的任意数字(包括1和10)random.randrange(1,10):随 ...