成人国产在线小视频_日韩寡妇人妻调教在线播放_色成人www永久在线观看_2018国产精品久久_亚洲欧美高清在线30p_亚洲少妇综合一区_黄色在线播放国产_亚洲另类技巧小说校园_国产主播xx日韩_a级毛片在线免费

資訊專欄INFORMATION COLUMN

python開發(fā)時幾種安全驗證的實現(xiàn)

int64 / 3544人閱讀

摘要:在這兩種情況下,如果你簽名的都是用戶,那么該用戶可以在激活賬戶和升級賬戶時,復(fù)用的可變部分。變量是一個元組,包括一個透視變換的系數(shù)。

額,一個突然的交流讓我想起來我耽擱許久各種驗證的實現(xiàn)遲遲沒做過
趁著這個機(jī)會就搞了一下
分為三部分:郵箱驗證,短信驗證,圖片驗證碼

郵箱驗證

這個部分是主要參考的經(jīng)典書籍-狗書
思路就是根據(jù)用戶某些信息通過JSON Web簽名生成token,然后再發(fā)送郵件驗證,經(jīng)典思路
生成和驗證函數(shù)都加載在模型中
完整代碼
itsdangerous中文文檔這里介紹了幾種簽名方式

token生成和驗證
TimedJSONWebSignatureSerializer,看這個表面詞的意思可以看出這里序列化加入了當(dāng)前時間
這也是實現(xiàn)設(shè)置過期時間的依據(jù)吧
查看itsdangerous源碼可以看到具體的加密方式
from itsdangerous import (TimedJSONWebSignatureSerializer as Serializer, BadSignature, SignatureExpired)
...
class User(db.Model):
    __tablename__ = "user"
    id = db.Column(db.Integer,primary_key=True)
    name=db.Column(db.String(64),unique=True,index=True)

    def genter_auth_token(self,expiration=300): #設(shè)置有效期
        s=Serializer(current_app.config["SECRET_KEY"],expires_in=expiration)
        return s.dumps({"code":self.name}) #將用戶名當(dāng)作簽名對象

    @staticmethod
    def verify_auth_token(token):
        s=Serializer(current_app.config["SECRET_KEY"])
        try:
            data=s.loads(token) #加載數(shù)據(jù)
        except BadSignature:
            return None
        except SignatureExpired:
            return None
        return data

同時這里itdangerous類的簽名方式都可以接收一個salt
文檔中這樣描述了salt的作用:

itsdangerous中的鹽,是為了一個截然不同的目的而產(chǎn)生的。你可以將它視為成命名空間
假設(shè)你想簽名兩個鏈接。你的系統(tǒng)有個激活鏈接,用來激活一個用戶賬戶,并且你有一個升級鏈接,可以讓一個用戶賬戶升級為付費(fèi)用戶,這兩個鏈接使用email發(fā)送。在這兩種情況下,如果你簽名的都是用戶ID,那么該用戶可以在激活賬戶和升級賬戶時,復(fù)用URL的可變部分?,F(xiàn)在你可以在你簽名的地方加上更多信息(如升級或激活的意圖),但是你也可以用不同的鹽

即只有使用相同鹽的序列化器才能成功把值加載出來

def genter_auth_token(self,expiration=300):
    s=Serializer(current_app.config["SECRET_KEY"],salt="activate-salt",expires_in=expiration)
    return s.dumps({"code":self.name})

@staticmethod
def verify_auth_token(token):
    s=Serializer(current_app.config["SECRET_KEY"],salt="activate-salt")
圖片驗證碼

這個驗證碼可以直接調(diào)用一些平臺的智能驗證,也可以用另一種
另一個也許是比較傳統(tǒng)的思路,就是自己生成的圖片水印,保存驗證碼
python和php里都有相應(yīng)的圖片操作方法,這里就寫下python的

流程就是生成任意的數(shù)字,保存,添加圖片水印

這里肯定要用的python強(qiáng)大的圖片處理庫PIL,其中用到了
加線條,濾鏡等增加干擾
下面是完整代碼,該做注釋的地方我已經(jīng)加了注釋
看代碼之前,最好先好好看下PIL官方文檔,和一些基本概念
部分我參考的博文也貼在了文末

#!/usr/bin/env python 
#coding=utf-8
import os
import random
from flask import Flask,send_from_directory
from PIL import Image,ImageFont,ImageDraw,ImageFilter

app=Flask(__name__)
app.debug=True

class picture:
    def __init__(self):
        self.size = (240,60)
        self.mode="RGB"
        self.color="white"
        self.font = ImageFont.truetype("C:WindowsFontsArial.ttf", 36) #設(shè)置字體大小

    def randChar(self):
        basic="23456789abcdefghijklmnpqrstwxyzABCDEFGHIJKLMNPQRSTWXYZ"
        return basic[random.randint(0,len(basic)-1)] #隨機(jī)字符

    def randBdColor(self):
        return (random.randint(64,255),random.randint(64,255),random.randint(64,255)) #背景

    def randTextColor(self):
        return (random.randint(32, 127), random.randint(32, 127), random.randint(32, 127)) #隨機(jī)顏色

    def proPicture(self):
        new_image=Image.new(self.mode,self.size,self.color) #創(chuàng)建新圖像有三個默認(rèn)參數(shù):尺寸,顏色,模式
        drawObject=ImageDraw.Draw(new_image) #創(chuàng)建一個可以對image操作的對象
        line_num = random.randint(4,6) # 干擾線條數(shù)
        for i in range(line_num):
            #size=(240,60)
            begin = (random.randint(0, self.size[0]), random.randint(0, self.size[1]))
            end = (random.randint(0, self.size[0]), random.randint(0, self.size[1]))
            drawObject.line([begin, end], self.randTextColor())

        for x in range(240):
            for y in range(60):
                tmp = random.randint(0,50)
                if tmp>30: #調(diào)整干擾點數(shù)量
                    drawObject.point((x,y),self.randBdColor())

        randchar=""  
        for i in range(5):
            rand=self.randChar()
            randchar+=rand
            drawObject.text([50*i+10,10],rand,self.randTextColor(),font=self.font) #寫入字符

        new_image = new_image.filter(ImageFilter.SHARPEN) # 濾鏡    

        return new_image,randchar
@app.route("/")
def get_file(filename):
    return send_from_directory(os.getcwd(),filename)

@app.route("/")
def index():
    test=picture()
    image,code=test.proPicture()
    image.save("new.jpg")
    url="http://127.0.0.1:5000/new.jpg"
    return "
"+"圖中的code為:"+code #這里有緩存,需要CTRL+F5才會有效果 if __name__=="__main__": app.run()

另外,有的前輩會再加入了扭曲圖像增加分辨難度

# 圖形扭曲參數(shù) 
params = [1 - float(random.randint(1, 2)) / 100, 
              0, 
              0, 
              0, 
              1 - float(random.randint(1, 10)) / 100, 
              float(random.randint(1, 2)) / 500, 
              0.001, 
              float(random.randint(1, 2)) / 500 
              ] 
img = img.transform(size, Image.PERSPECTIVE, params) # 創(chuàng)建扭曲

這里有篇文章詳細(xì)的介紹了下:

對當(dāng)前圖像進(jìn)行透視變換,產(chǎn)生給定尺寸的新圖像。
變量data是一個8元組(a,b,c,d,e,f,g,h),包括一個透視變換的系數(shù)。對于輸出圖像中的每個像素點,新的值來自于輸入圖像的位置的(a x + b y + c)/(g x + h y + 1), (d x+ e y + f)/(g x + h y + 1)像素,使用最接近的像素進(jìn)行近似

這個的源定義就牽涉到了一個仿射變換,涉及一些數(shù)學(xué)的計算
看得我有點懵逼,就沒加到我的代碼中,先留坑

這個地方現(xiàn)在很多網(wǎng)站會使用另一種回答問題的方式,這個方法的實現(xiàn)
我個人感覺也是應(yīng)該也是相同的手段,只是將隨機(jī)的字符串改為問題,將驗證方式改為答案
不過這里或許要把問題和答案存進(jìn)數(shù)據(jù)庫,更方便點,也才能實現(xiàn)

短信驗證

有時候想自己是不是出生太晚了。。。。。想寫的東西,都能搜到很好的博文,如下:flask開發(fā)restful api系列(5)-短信驗證碼
這里云通訊是文中所用平臺的開發(fā)文檔,不過平臺可以自由選擇,結(jié)果都是一樣
這里就簡化一下前輩的代碼,把關(guān)于驗證碼處理的重點代碼擼了出來,用到了Redis,我也趁機(jī)學(xué)了一波,的確挺好用的

import redis
import random

phonenumber=188888888
#這里可以利用正則過濾一下電話號碼,比如:
#/^(13[0-9]|14[5-9]|15[0-9]|16[6]|17[0-8]|18[0-9]|19[8-9])d{8}$/

conn=redis.StrictRedis(host="127.0.0.1",port=6379)

def producCode():
    verifyCode=str(random.randint(100000,999999))

    pipe=conn.pipeline() #添加管道,可以一次連接執(zhí)行多次命令
    pipe.set("phone%s"%phonenumber,verifyCode)
    pipe.expire("phone%s"%phonenumber,60) #設(shè)置過期時間一分鐘
    pipe.execute()

def checkCode():
    pipe=conn.pipeline() #添加管道,可以一次連接執(zhí)行多次命令
    pipe.set("postNum%s"%phonenumber,"0")
    validate_number = request.get_json().get("validate_number")
    pipe.incr("postNum%s"%phonenumber) #記錄提交次數(shù)防止爆破
    if conn.get("postNum%s"%phonenumber)>3:
        pass
    ...
    if validate_number != validate_number_in_redis:
        return jsonify({"code": 0, "message": "驗證沒有通過"})
    pipe.set("is_validate:%s" % phone_number, "1") #通過驗證碼設(shè)置value為1
    pipe.expire("is_validate:%s" % phone_number, 120)
    pipe.execute()

    return jsonify({"code": 1, "message": "驗證通過"})
def postMessage():
    result=conn.get("phone%s"%phonenumber)
    #此時如果通過驗證碼,result為1,否則為0
    ...
    #剩下的其他操作

這里提到了泄露接口導(dǎo)致驗證碼爆破的情況,我也添加了一些代碼
另外就是在某些功能模塊,也易出現(xiàn)漏洞,比如修改資料處,驗證碼不僅僅要與phone一致
也要檢查用戶名的一致性,要不然如果只是通過驗證碼,用戶修改為自己的號碼,驗證碼手機(jī)號都通過驗證
(感覺一般人不會出現(xiàn)這種錯誤)

而你的代碼又是直接傳入用戶名進(jìn)行修改操作,這將可能導(dǎo)致任意用戶重置密碼
或者你的代碼直接將phone作為索引進(jìn)行修改

Github完整代碼地址

參考文章: 狗書authentication
雜項之圖像處理pillow
PIL一些基本概念
PIL中的Image模塊
Python PIL ImageDraw和ImageFont模塊學(xué)習(xí)
Python圖像處理庫PIL的ImageFilter模塊介紹
Redis中文文檔
redis-py

文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請注明本文地址:http://systransis.cn/yun/41003.html

相關(guān)文章

  • Ant Design UI組件之Select踩坑

    摘要:了解到項目使用版本是版本的,懷疑是版本問題。在了解到問題的根源后,修改相應(yīng)代碼。再去查看相應(yīng)官方文檔由于英文不好,沒有理解到官方文檔的意思。還是需要加強(qiáng)對英文官方文檔的理解。前言 1. 在使用Ant design UI組件時總會遇到一些奇奇怪怪的問題,在本篇中將總結(jié)在使用Select時幾種常見的問題 遇到的問題 在初始化Select值,如何根據(jù)value顯示對應(yīng)文本 showImg(http...

    NotFound 評論0 收藏0
  • 發(fā)布你自己輪子 - PyPI打包上傳實踐

    摘要:推薦遵循語義化版本號規(guī)則,簡單說就像這樣作者姓名和郵箱地址不一定要和你的賬號一致。上傳并完成發(fā)布你可以任選以下兩種方式之一發(fā)布你的輪子。文件已經(jīng)存在了,你每一次上次都應(yīng)該更新版本號。 本文僅討論上傳相關(guān)的步驟,關(guān)于如何給寫一個setup.py 請參閱官方文檔: https://docs.python.org/2/dis... 上傳前的注意事項 假設(shè)你的包已經(jīng)開發(fā)完成,并且根目錄必須要...

    sunny5541 評論0 收藏0
  • 現(xiàn)代后端開發(fā)者必備技能-2018版

    摘要:現(xiàn)在開始創(chuàng)建一個包并分發(fā)給其他人使用,并確保遵循你迄今為止學(xué)到的標(biāo)準(zhǔn)和最佳實踐。第步實踐對于練習(xí),繼續(xù)編寫單元測試,以完成目前為止所做的實際任務(wù),特別是你在步驟中所做的練習(xí)。 今天的Web開發(fā)與幾年前完全不同,有很多不同的東西可以很容易地阻止任何人進(jìn)入Web開發(fā)。這是我們決定制作這些循序漸進(jìn)的視覺指南的原因之一,這些指南展示了更大的圖景,并讓任何人清楚了解他們在網(wǎng)頁開發(fā)中扮演的角色。 ...

    eternalshallow 評論0 收藏0
  • 理解JWT(JSON Web Token)認(rèn)證及python實踐

    摘要:認(rèn)證服務(wù)器,即服務(wù)提供商專門用來處理認(rèn)證的服務(wù)器。它與認(rèn)證服務(wù)器,可以是同一臺服務(wù)器,也可以是不同的服務(wù)器??蛻舳耸褂蒙弦徊将@得的授權(quán),向認(rèn)證服務(wù)器申請令牌。認(rèn)證服務(wù)器對客戶端進(jìn)行認(rèn)證以后,確認(rèn)無誤,同意發(fā)放令牌。 最近想做個小程序,需要用到授權(quán)認(rèn)證流程。以前項目都是用的 OAuth2 認(rèn)證,但是Sanic 使用OAuth2 不太方便,就想試一下 JWT 的認(rèn)證方式。這一篇主要內(nèi)容是 ...

    BigTomato 評論0 收藏0
  • 如何使用密碼保護(hù)以太坊JSON-RPCAPI?

    摘要:本文面向以太坊智能合約應(yīng)用程序開發(fā)人員,并討論如何在密碼保護(hù)后,安全地運(yùn)行你的以太坊節(jié)點,以便通過進(jìn)行安全輸出。以太坊,主要是針對工程師使用進(jìn)行區(qū)塊鏈以太坊開發(fā)的詳解。 本文面向以太坊智能合約應(yīng)用程序開發(fā)人員,并討論如何在密碼保護(hù)后,安全地運(yùn)行你的以太坊節(jié)點,以便通過Internet進(jìn)行安全輸出。 Go Ethereum(geth)是以太坊節(jié)點最受歡迎的軟件。其他流行的以太坊實現(xiàn)是Pa...

    Zachary 評論0 收藏0

發(fā)表評論

0條評論

最新活動
閱讀需要支付1元查看
<