天天看點

别無分号隻此一家,Python3接入支付寶身份認證接口

目前國内身份認證體系做的比較不錯的大抵就是支付寶和微信兩家了,支付寶的身份驗證基于支付寶app的實人認證能力,采用多因子認證技術快速得出認證結果,對于多因子認證技術不太了解的朋友可移步:别讓你的伺服器(vps)淪為殭屍電腦(ssh暴力破解),密鑰驗證、雙向因子登入值得擁有 進行了解。其作用主要是為了解決線上實人開戶、賬号實名認證、賬号實人登入等場景中個人身份的識别問題,比如你某一天突然心血來潮想當一把韭菜炒炒股,又不想去人多眼雜的營業廳,是以利用app遠端開戶,開戶的過程中,你怎麼證明“你是你本人”的問題。

首先,老規矩,做一下前置任務,注冊螞蟻金服開放平台:https://open.alipay.com/

随後建立應用

别無分号隻此一家,Python3接入支付寶身份認證接口

這裡我們建立一個網頁應用。

之後就是為應用設定秘鑰,點開秘鑰管理頁面

别無分号隻此一家,Python3接入支付寶身份認證接口

對于沒接觸過秘鑰的朋友,可以參考這篇文章:在Mac系統下生成新版支付寶(2019年4月)支付接口私鑰和公鑰。

将生成好的應用公鑰配置到頁面上,同時将應用私鑰和支付寶公鑰分别複制一份,過一會兒會用到。

最後,别忘了記錄一下應用的appid,以及確定您的應用已經開通了支付寶身份認證接口:

别無分号隻此一家,Python3接入支付寶身份認證接口

OK,萬事俱備隻欠代碼,下面我們利用支付寶官方的sdk完成刷臉認證。

首先安裝對應的庫:

pip3 install alipay-sdk-python==3.3.398           

一般情況下,我們使用bug相對少的最新版。

支付寶身份認證的流程大體分為三步:身份認證初始化服務(alipay.user.certify.open.initialize)->身份認證開始認證(alipay.user.certify.open.certify)->身份認證記錄查詢(alipay.user.certify.open.query)

我們首先來開發身份認證初始化服務,參考官方文檔:https://opendocs.alipay.com/apis/api_2/alipay.user.certify.open.initialize

通過傳入訂單号、認證人名字、身份證(或者港澳台證件)等參數,接口會傳回一個唯一認證号:certify_id,後續通過certify_id就可以進行實體認證或者實體查詢,編寫test_alipay.py:

import json

from alipay.aop.api.AlipayClientConfig import AlipayClientConfig
from alipay.aop.api.DefaultAlipayClient import DefaultAlipayClient
from alipay.aop.api.request.AlipayUserCertifyOpenInitializeRequest import AlipayUserCertifyOpenInitializeRequest, AlipayUserCertifyOpenInitializeModel
from alipay.aop.api.request.AlipayUserCertifyOpenCertifyRequest import AlipayUserCertifyOpenCertifyRequest

from alipay.aop.api.request.AlipayUserCertifyOpenQueryRequest import AlipayUserCertifyOpenQueryRequest

from alipay.aop.api.response.AlipayUserCertifyOpenCertifyResponse import AlipayUserCertifyOpenCertifyResponse

import random
import string

import ssl
ssl._create_default_https_context = ssl._create_unverified_context
from MyQR import myqr

ali_public_key = '''
  -----BEGIN PUBLIC KEY-----
  MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAuv2nESi3dAvGdHcxNs1TjIMxbJt4IrhBjMZcIrBALGGHxuQVCPZjci4lcGt+oBmWGAlt3F
這裡是支付寶公鑰
  -----END PUBLIC KEY-----
  '''
app_private_key = '''
  -----BEGIN RSA PRIVATE KEY-----
  MIIEogIBAAKCAQEAnpWCj6SVbWuuldIGns4K1PB+Ir17v6BNXRvyYY3jxu2ky這裡是應用私鑰
  -----END RSA PRIVATE KEY-----
  '''

config = AlipayClientConfig()
config.app_id = '應用id'
config.app_private_key = app_private_key
config.alipay_public_key = ali_public_key           

将應用id、支付寶公鑰以及應用私鑰配置好,這裡注意秘鑰最好加上開始與結束符。随後編寫初始化邏輯:

#  身份初始化
def ali_init():

    client = DefaultAlipayClient(config)
    request = AlipayUserCertifyOpenInitializeRequest()
    request.biz_content = {
        'outer_order_no': ''.join(random.sample(string.ascii_letters, 32)),
        'biz_code': 'FACE_ALIPAY_SDK',
        'identity_param': {
            "identity_type": "CERT_INFO",
            "cert_type": "IDENTITY_CARD",
            "cert_name": "姓名",
            "cert_no": "身份證号"
        },
        'merchant_config': {
            "return_url": "https://ali.v3u.cn"
        },
    }

    #print(request.get_params())
    response = client.execute(request)
    #print(response)
    # 擷取參數
    certify_id = json.loads(response).get('certify_id')
    print(certify_id)           

這裡訂單号不能重複,是以使用随機子產品進行生成,通路AlipayUserCertifyOpenInitializeRequest接口,測試一下:

liuyue:mydjango liuyue$ python3 "/Users/liuyue/wodfan/work/mydjango/mydjango/tests.py"
ff8182725aae897e262fa6d0fe24692c           

可以看到接口傳回了一個32位的certify_id。此時,我們可以進行第二步:身份認證開始認證(alipay.user.certify.open.certify),官方文檔:https://opendocs.alipay.com/apis/api_2/alipay.user.certify.open.certify

# 開始身份認證
def auth_start(client, certify_id):

    #client = DefaultAlipayClient(config)
    request = AlipayUserCertifyOpenCertifyRequest()

    request.biz_content = {'certify_id': str(certify_id)}

    print(certify_id)
    #print(request.get_params())

    response = client.page_execute(request, http_method="GET")
    print(response)
    myqr.run(words=response)           

将剛剛傳回的certify_id作為參數請求AlipayUserCertifyOpenCertifyRequest接口,注意采用get方式,該接口會傳回一個支付寶的連結,測試一下:

def ali_init():

    client = DefaultAlipayClient(config)
    request = AlipayUserCertifyOpenInitializeRequest()
    request.biz_content = {
        'outer_order_no': ''.join(random.sample(string.ascii_letters, 32)),
        'biz_code': 'FACE_ALIPAY_SDK',
        'identity_param': {
            "identity_type": "CERT_INFO",
            "cert_type": "IDENTITY_CARD",
            "cert_name": "收委",
            "cert_no": "260104197909275964"
        },
        'merchant_config': {
            "return_url": "https://lingxi.zfmix.com/user/user_authentication/"
        },
    }

    #print(request.get_params())
    response = client.execute(request)
    #print(response)
    # 擷取參數
    certify_id = json.loads(response).get('certify_id')
    print(certify_id)

    auth_start(client, certify_id)           

傳回值:

liuyue:mydjango liuyue$ python3 "/Users/liuyue/wodfan/work/mydjango/mydjango/tests.py"
65bf2091bc757d1e7b7dff7f3af619f6
65bf2091bc757d1e7b7dff7f3af619f6
https://openapi.alipay.com/gateway.do?timestamp=2021-01-06+20%3A09%3A21&app_id=2021002119690109&method=alipay.user.certify.open.certify&charset=utf-8&format=json&version=1.0&sign_type=RSA2&sign=HYK0RJjbLLFqBplL2av9sqkgykfKV1xUKgw0Fo0oRWXoC9H%2BjTDZZJElmXVi2jbfBzikac%2B5iqETK0i%2Bz9MpBfJUC8eoCjbRyUUNTrxX7003toEKz8utabOALSlwQcutFSbVbTthB5GXzpSzHZChkiZwQVUVCw3oHholUw7%2B2RnLRno%2BmwRyi6mJ2296wQvqE962LpGKV%2FxNF5O6UaKFEyoKceOztxI%2FnXIfcRfH6mgrUTP7NhLSpLvBdIbgcuCNARmS04ZN6BL7UwjkvNglNRgAydhypJqJqv0sBXRJQ8hDfIsLV3jACpgyarJ4tQeEJP4CfTobFhA2nLsYnnEbbw%3D%3D&biz_content=%7B%22certify_id%22%3A%2265bf2091bc757d1e7b7dff7f3af619f6%22%7D
line 16: mode: byte
liuyue:mydjango liuyue$           

這個連結隻要使用支付寶app進行通路,就可以跳轉到刷臉認證頁面,但是如果讓普通使用者粘貼連結到支付寶太過于繁瑣,是以我們利用myqr子產品将該連結制作成二維碼,使用者隻需要用支付寶app對二維碼進行掃描即可:

pip3 install myqr           

認證接口:

response = client.page_execute(request, http_method="GET")
print(response)
myqr.run(words=response)           

随後項目内會生成一個qrcode.png

别無分号隻此一家,Python3接入支付寶身份認證接口

打開支付寶app,對其進行掃碼操作:

别無分号隻此一家,Python3接入支付寶身份認證接口

最後,在身份認證完成後,調用身份認證記錄查詢(alipay.user.certify.open.query)查詢認證狀态和相關資料。官方文檔:https://opendocs.alipay.com/apis/api_2/alipay.user.certify.open.query

# 查詢接口
def auth_check(client, certify_id):

    print(certify_id)

    request = AlipayUserCertifyOpenQueryRequest()
    request.biz_content = {'certify_id': str(certify_id)}

    response = client.execute(request)

    print(response)           

同樣傳入certify_id,接口為AlipayUserCertifyOpenQueryRequest,測試一下:

liuyue:mydjango liuyue$ python3 "/Users/liuyue/wodfan/work/mydjango/mydjango/tests.py"
f35030276a08b27cdc67c26a18f57650
f35030276a08b27cdc67c26a18f57650
{"code":"10000","msg":"Success","material_info":"{}","passed":"F"}           

如果已經認證成功會傳回T,反之則是F。

需要注意的是,在沒有刷臉情況下的certify_id 有效期是23個小時,認證成功後,調用查詢接口certify_id是3個月的有效期。

結語:總體而言,坑不是很多,主要鍛煉的是大家閱讀文檔的能力,或者說的更準确一點:通過閱讀了解将文檔轉化為代碼的能力,有意思的一點是,如果大家通讀了支付寶的文檔,會發現如果身份認證成功,是不可以取消的,也就是身份認證不可逆,也就是說,支付寶如果想利用你的資訊幹點什麼的話,你沒有任何反抗的能力,是以說到底,這是一個使用者隐私使用權的問題,大多數情況下,國人願意容忍國家擷取或者使用自己的隐私,是因為他們覺得自己仍有監督與幹預政府機構的能力或者管道,無論是以間接還是比較激進的方式。而人們不願意像支付寶這種商業寡頭擷取并運用自己的隐私,也正是因為人們知道自己在面對此類商業機構對自己隐私的利用或者濫用時,自己隻能幹瞪眼,搏手無策。