Authlib強大OAuth框架入門

基於Python的Authlib是集全部主流WebAPI權限認證協議的客戶端、服務端、底層實現、高層架構於一身的強大工具庫。html

參考官方:Authlib: Python Authenticationapi

Authlib幾乎是能將RFC全部相關的API認證協議都包括進來了,甚至從協議的底層實現、高層架構,從客戶端到服務端都能實現的,當之無愧稱爲Monolithic project 的一個項目。瀏覽器

目前Authlib支持的Authentication協議有:服務器

  • OAuth 1.0
  • OAuth 2.0
  • JWT
  • many more...

安裝:cookie

$ pip install Authlib

Oauth2.0客戶端驗證

參考官方:Authlib - Client Guide - OAuth 2 Sessionsession

Authlib中用來登陸驗證OAuth2.0的對象叫Session,其中包括了全部相關的驗證所需方法函數。架構

from authlib.client import OAuth2Session

# 生成session,用來以後的建立URL、獲取token、刷新token等全部動做
session = OAuth2Session(
    client_id='Your Client ID', client_secret='Your Client Secret',
    scope='user:email',  # 這個受權範圍根據每一個API有所不一樣
    redirect_uri='https://MyWebsite.com/callback'
)


# 生成URL
uri, state = session.create_authorization_url(
    'https://目標網址的受權入口/authorize'
)
print(uri)

# 「手動」打開瀏覽器訪問URI,登陸API賬戶,點擊受權,而後獲取最終的URL
# 或者本身有服務器的話,能夠本身接收
#。。。
# 將callback返回的URL複製下來,由於其中包含受權code
authorization_response = 'https://MyWebsite.com/callback?code=42..e9&state=d..t'

# 用得到的Code去訪問access_token入口
tokens = session.fetch_access_token(
    access_token_url='https://目標網址的受權入口/api/access_token',
    authorization_response=authorization_response
)
print(tokens)  #返回字典格式: {'access_token': 'e..ad', 'token_type': 'bearer', 'scope': 'user:email'}


# 過時後,刷新token。需重建session對象:
session = OAuth2Session(
    client_id='Your Client ID', client_secret='Your Client Secret',
    scope='user:email', state=state, redirect_uri='https://MyWebsite.com/callback'
)
new_tokens = session.refresh_token(
    access_token_url, refresh_token=tokens['refresh_token']
)
print('[Refreshed tokens]:', new_tokens)

設置的callback或redirect_url不存在怎麼獲取Code?

在調試過程當中,若是咱們向上面同樣手動去打開瀏覽器複製URL,再複製迴應過來的URL是很麻煩的。ide

Oauth2的邏輯就是:要求各類客戶本身在本身的瀏覽器裏登陸賬戶,而後給你的App受權。因此這一步redirect_url是躲不過的。可是咱們測試過程當中,還沒來得及專門建一個服務器或網頁來接收這個callback回調怎麼辦呢?
有辦法!函數

方法一:直接截取

咱們能夠在第一次登陸並受權後,複製cookies,而後在測試中直接使用requests帶着cookies登陸信息去訪問,就再也不須要手動打開瀏覽器了:工具

raw_cookies = """ 這裏是你複製過來的cookies """
cookies = dict([line.split("=", 1) for line in raw_cookies.strip().split("; ")])

try:
    r = requests.get(uri, cookies=cookies, allow_redirects=True)
except requests.exceptions.ConnectionError as e:
    print( '[Final URL]: ', e.request.url )
    authorization_response = e.request.url

因爲你最開始設置的callback是公網上的某個網址,應該是不存在的(只要你沒有設置的話)。
因此,這裏去request的時候,確定會報錯,且是ConnectionError。因此咱們能夠將最終報錯的URL獲取到,這個裏面就包含了咱們想要的Code碼。

方法二:更改本地hosts

若是本地已經搭建了測試服務器,好比Nginx或Flask,這種方法更簡單。

好比在供應商中設定的redirect_url爲http://example.com/callback,那麼只需簡單編輯hosts:

# /etc/hosts

127.0.0.1   example.com

那麼,只要本機設置了Nginx或Flask等服務器,只須要獲取127.0.0.1/callback便可獲得須要的內容。

相關文章
相關標籤/搜索