在Web應用的開發過程中,有一些任務並不是我們自己能夠完成的。例如,我們的Web專案中需要做個人或企業的實名認證,很顯然我們並沒有能力判斷使用者提供的認證資訊的真實性,這個時候我們就要藉助三方平臺提供的服務來完成該項操作。再比如說,我們的專案中需要提供線上支付功能,這類業務通常也是藉助支付閘道器來完成而不是自己去實現,我們只需要接入像微信、支付寶、銀聯這樣的三方平臺即可。
在專案中接入三方平臺基本上就兩種方式:API接入和SDK接入。
- API接入指的是透過訪問三方提供的URL來完成操作或獲取資料。國內有很多這樣的平臺提供了大量常用的服務,例如聚合資料上提供了生活服務類、金融科技類、交通地理類、充值繳費類等各種型別的API。我們可以透過Python程式發起網路請求,透過訪問URL獲取資料,這些API介面跟我們專案中提供的資料介面是一樣的,只不過我們專案中的API是供自己使用的,而這類三方平臺提供的API是開放的。當然開放並不代表免費,大多數能夠提供有商業價值的資料的API都是需要付費才能使用的。
- SDK接入指的是透過安裝三方庫並使用三方庫封裝的類、函式來使用三方平臺提供的服務的方式。例如我們剛才說到的接入支付寶,就需要先安裝支付寶的SDK,然後透過支付寶封裝的類和方法完成對支付服務的呼叫。
下面我們透過具體的例子來講解如何接入三方平臺。
一個Web專案有很多地方都可以用到簡訊服務,例如:手機驗證碼登入、重要訊息提醒、產品營銷簡訊等。要實現傳送簡訊的功能,可以透過接入簡訊閘道器來實現,國內比較有名的簡訊閘道器包括:雲片簡訊、網易雲信、螺絲帽、SendCloud等,這些簡訊閘道器一般都提供了免費試用功能。下面我們以螺絲帽平臺為例,講解如何在專案中接入簡訊閘道器,其他平臺操作基本類似。
-
註冊賬號,新使用者可以免費試用。
-
登入到管理後臺,進入簡訊版塊。
-
點選“觸發傳送”可以找到自己專屬的API Key(身份標識)。
-
點選“簽名管理”可以新增簡訊簽名,簡訊都必須攜帶簽名,免費試用的簡訊要在簡訊中新增“【鐵殼測試】”這個簽名,否則簡訊無法傳送。
-
點選“IP白名單”將執行Django專案的伺服器地址(公網IP地址,本地執行可以開啟xxx網站檢視自己本機的公網IP地址)填寫到白名單中,否則簡訊無法傳送。
-
如果沒有剩餘的簡訊條數,可以到“充值”頁面選擇“簡訊服務”進行充值。
接下來,我們可以透過呼叫螺絲帽簡訊閘道器實現傳送簡訊驗證碼的功能,程式碼如下所示。
def send_mobile_code(tel, code):
"""傳送簡訊驗證碼"""
resp = requests.post(
url='http://sms-api.luosimao.com/v1/send.json',
auth=('api', 'key-自己的APIKey'),
data={
'mobile': tel,
'message': f'您的簡訊驗證碼是{code},打死也不能告訴別人喲。【Python小課】'
},
verify=False
)
return resp.json()
執行上面的程式碼需要先安裝requests
三方庫,這個三方庫封裝了HTTP網路請求的相關功能,使用起來非常的簡單,我們在之前的內容中也講到過這個三方庫。send_mobile_code
函式有兩個引數,第一個引數是手機號,第二個引數是簡訊驗證碼的內容,第5行程式碼需要提供自己的API Key,就是上面第2步中檢視到的自己的API Key。請求螺絲帽的簡訊閘道器會返回JSON格式的資料,對於上面的程式碼如果返回{'err': 0, 'msg': 'ok'}
,則表示簡訊傳送成功,如果err
欄位的值不為0
而是其他值,則表示簡訊傳送失敗,可以在螺絲帽官方的開發文件頁面上檢視到不同的數值代表的含義,例如:-20
表示餘額不足,-32
表示缺少簡訊簽名。
可以在檢視函式中呼叫上面的函式來完成傳送簡訊驗證碼的功能,稍後我們可以把這個功能跟使用者註冊結合起來。
生成隨機驗證碼和驗證手機號的函式。
import random
import re
TEL_PATTERN = re.compile(r'1[3-9]\d{9}')
def check_tel(tel):
"""檢查手機號"""
return TEL_PATTERN.fullmatch(tel) is not None
def random_code(length=6):
"""生成隨機簡訊驗證碼"""
return ''.join(random.choices('0123456789', k=length))
傳送簡訊驗證碼的檢視函式。
@api_view(('GET', ))
def get_mobilecode(request, tel):
"""獲取簡訊驗證碼"""
if check_tel(tel):
redis_cli = get_redis_connection()
if redis_cli.exists(f'vote:block-mobile:{tel}'):
data = {'code': 30001, 'message': '請不要在60秒內重複傳送簡訊驗證碼'}
else:
code = random_code()
send_mobile_code(tel, code)
# 透過Redis阻止60秒內容重複傳送簡訊驗證碼
redis_cli.set(f'vote:block-mobile:{tel}', 'x', ex=60)
# 將驗證碼在Redis中保留10分鐘(有效期10分鐘)
redis_cli.set(f'vote2:valid-mobile:{tel}', code, ex=600)
data = {'code': 30000, 'message': '簡訊驗證碼已傳送,請注意查收'}
else:
data = {'code': 30002, 'message': '請輸入有效的手機號'}
return Response(data)
說明:上面的程式碼利用Redis實現了兩個額外的功能,一個是阻止使用者60秒內重複傳送簡訊驗證碼,一個是將使用者的簡訊驗證碼保留10分鐘,也就是說這個簡訊驗證碼的有效期只有10分鐘,我們可以要求使用者在註冊時提供該驗證碼來驗證使用者手機號的真實性。
當我們提到雲端儲存這個詞的時候,通常是指把資料存放在由第三方提供的虛擬伺服器環境下,簡單的說就是將某些資料或資源透過第三平臺託管。一般情況下,提供雲端儲存服務的公司都運營著大型的資料中心,需要雲端儲存服務的個人或組織透過向其購買或租賃儲存空間來滿足資料儲存的需求。在開發Web應用時,可以將靜態資源,尤其是使用者上傳的靜態資源直接置於雲端儲存服務中,雲端儲存通常會提供對應的URL使得使用者可以訪問該靜態資源。國內外比較有名的雲端儲存服務(如:亞馬遜的S3、阿里的OSS2等)一般都物美價廉,相比自己架設靜態資源伺服器,雲端儲存的代價更小,而且一般的雲端儲存平臺都提供了CDN服務,用於加速對靜態資源的訪問,所以不管從哪個角度出發,使用雲端儲存的方式管理Web應用的資料和靜態資源都是非常好的選擇,除非這些資源涉及到個人或商業隱私,否則就可以託管到雲端儲存中。
下面我們以接入七牛雲為例,講解如何實現將使用者上傳的檔案儲存到七牛雲端儲存。七牛雲是國內知名的雲計算及資料服務提供商,七牛雲在海量檔案儲存、CDN、影片點播、互動直播以及大規模異構資料的智慧分析與處理等領域都有自己的產品,而且非付費使用者也可以免費接入,使用其提供的服務。下面是接入七牛雲的流程:
-
註冊賬號,登入管理控制檯。
-
選擇左側選單中的物件儲存。
-
在空間管理中選擇新建空間(例如:myvote),如果提示空間名稱已被佔用,更換一個再嘗試即可。注意,建立空間後會提示繫結自定義域名,如果暫時還沒有自己的域名,可以使用七牛雲提供的臨時域名,但是臨時域名會在30天后被回收,所以最好準備自己的域名(域名需要備案,不清楚如何操作的請自行查閱相關資料)。
-
在網頁的右上角點選個人頭像中的“金鑰管理”,檢視自己的金鑰,稍後在程式碼中需要使用AK(AccessKey)和SK(SecretKey)兩個金鑰來認證使用者身份。
-
點選網頁上方選單中的“文件”,進入到七牛開發者中心,選擇導航選單中的“SDK&工具”並點選“官方SDK”子選單,找到Python(服務端)並點選“文件”檢視官方文件。
接下來,只要安裝官方文件提供的示例,就可以接入七牛雲,使用七牛雲提供的雲端儲存以及其他服務。首先可以透過下面的命令安裝七牛雲的三方庫。
pip install qiniu
接下來可以透過qiniu
模組中的put_file
和put_stream
兩個函式實現檔案上傳,前者可以上傳指定路徑的檔案,後者可以將記憶體中的二進位制資料上傳至七牛雲,具體的程式碼如下所示。
import qiniu
AUTH = qiniu.Auth('金鑰管理中的AccessKey', '金鑰管理中的SecretKey')
BUCKET_NAME = 'myvote'
def upload_file_to_qiniu(key, file_path):
"""上傳指定路徑的檔案到七牛雲"""
token = AUTH.upload_token(BUCKET_NAME, key)
return qiniu.put_file(token, key, file_path)
def upload_stream_to_qiniu(key, stream, size):
"""上傳二進位制資料流到七牛雲"""
token = AUTH.upload_token(BUCKET_NAME, key)
return qiniu.put_stream(token, key, stream, None, size)
下面是一個檔案上傳的簡單前端頁。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>上傳檔案</title>
</head>
<body>
<form action="/upload/" method="post" enctype="multipart/form-data">
<div>
<input type="file" name="photo">
<input type="submit" value="上傳">
</div>
</form>
</body>
</html>
說明:前端如果使用表單實現檔案上傳,表單的method屬性必須設定為post,enctype屬性需要設定為multipart/form-data,表單中type屬性為file的input標籤,就是上傳檔案的檔案選擇器。
實現上傳功能的檢視函式如下所示。
from django.views.decorators.csrf import csrf_exempt
@csrf_exempt
def upload(request):
# 如果上傳的檔案小於2.5M,則photo物件的型別為InMemoryUploadedFile,檔案在記憶體中
# 如果上傳的檔案超過2.5M,則photo物件的型別為TemporaryUploadedFile,檔案在臨時路徑下
photo = request.FILES.get('photo')
_, ext = os.path.splitext(photo.name)
# 透過UUID和原來檔案的副檔名生成獨一無二的新的檔名
filename = f'{uuid.uuid1().hex}{ext}'
# 對於記憶體中的檔案,可以使用上面封裝好的函式upload_stream_to_qiniu上傳檔案到七牛雲
# 如果檔案儲存在臨時路徑下,可以使用upload_file_to_qiniu實現檔案上傳
upload_stream_to_qiniu(filename, photo.file, photo.size)
return redirect('/static/html/upload.html')
注意:上面的檢視函式使用了
csrf_exempt
裝飾器,該裝飾器能夠讓表單免除必須提供CSRF令牌的要求。此外,程式碼第11行使用了uuid
模組的uuid1
函式來生成全域性唯一識別符號。
執行專案嘗試檔案上傳的功能,檔案上傳成功後,可以在七牛雲“空間管理”中點選自己空間並進入“檔案管理”介面,在這裡可以看到我們剛才上傳成功的檔案,而且可以透過七牛雲提供的域名獲取該檔案。