Try   HackMD

Flask實作_WEB API_04_資源請求

tags: python flask api

我們已經成功的登入API Service並取得access token,現在要利用這個access token來取得我們想要的資源。

說明

依RFC6750中所定義,使用Bearer在發出請求的時候有三個地方可以出示你的access token:

  1. header
  2. body
  3. query string

上面三種方法建議使用的是第1種,不管如何是非常不建議使用第3種。

另外,對於access token的遺失與錯誤也是採用不同的回應,這部份可以參考RFC6750-3.1(error code)的說明。

實作

一樣的python文件繼續調整:

# 追加載入flask.request
from flask import request

class FakeSource(MethodView):
    def get(self):
        # 首先驗證token的確認性與效期,為了版面的簡潔並沒有做try,但實務上會建議做一下try except
        token_type, access_token = request.headers.get('Authorization').split(' ')
        if token_type != 'Bearer' or token_type is None:
            # 驗證token_type是否為Bearer
            pass

        s = TJSS(app.config['SECRET_KEY'])
        data = s.loads(access_token)
        return jsonify({'data': data['username']})

# 加入一條router
app.add_url_rule('/fake_source/', view_func=FakeSource.as_view('fake_source'))

啟動專案之後,另外啟動一個Python command line:

>>> import requests
>>> url = 'http://127.0.0.1:5000/author_token/'
>>> res = requests.post(url=url, data={'grant_type':'password', 'username': 'shaoe.chen', 'password': '123456'})
# 上面先取得access token,下面取得response的資料
>>> res_data = res_token.json()
# 定義request的header 相關request的格式可參考RFC6750(指使用Bearer)
>>> param={
            'Authorization': 'Bearer ' + res_data.get('access_token'),
            'Accept': 'application/json',
            'Content-Type': 'application/json'
        }
>>> res2 = requests.get(url2, headers=param)
>>> res2.json()
{'data': 'shaoe.chen'}

上面結果來看,我們成功的發出一個請求來取得我們想要的資源。

結果

這是一個非常粗糙的範例,只是單純的demo在取得access token之後如果希望取得相關資源的時候可以怎麼設置我們的api以及發出請求。

實際當我們上線的時候可能會面臨到一個跨網域的請求,即使是相同的domain,但是www.abc.comapi.abc.com就算是跨網域了,過往都會利用JSONP來處理,但目前來說都是使用CORS,這可以利用擴展flask-cors來幫我們達成,只需要在設置api的blueprint的時候讓系統知道這個blueprint接受跨域請求即可。這未來如果有實際案例的時候再說明。

最後,我們可以直接利用裝飾器以類似於flask-login的方式來保護api,也避免每一次都要寫一堆檢查,不過你也可以直接使用flask-httpauth,依需求設置吧,因為flask是自由的。