標籤

S3

Day28 - 用 S3 幫忙轉址到原有的服務上

前言

在之前的文章都有將 NotifyLINE Login所需要的靜態頁面放在 S3 上面,讓其他使用者去點,雖然把前端放在程式裡面用 render template 比較好,可是在求快的情況下我把靜態頁面寫完就扔上去了(被拖走),其實也可以透過這個方法去幫忙轉址,不過接下來我會用我的臉書做個範例提供參考~

實作

照著之前的範例來建立一個名為 facebook.nijialin.com 來做 S3 轉址的範例 建立完之後因為我們需要把網址公開給其他使用者點選,在第三個分頁中先把第一個選項的 Block all public access 更換成 off 狀態 到第二個按鈕選項選擇 Public access,暴力一點把所有選項都打開 🤣 前面都已經把權限開完,選擇Static Website hosting這個選項,這個是 S3 提供來讓他有另一種功能,不過我是覺得這功能在這邊有點奇怪 XD


接著就來到 Route 53,點選左欄的 Hosted Zone 點選上面藍色的按鈕,右邊會出現輸入的地方讓你填 這邊我會輸入跟 S3 bucket 的名字一樣,然後 Alias 選擇 Yes,下面輸入框點下去會看到自己剛剛輸入的 S3 website endpoints 建立完之後就可以在瀏覽器上輸入網址,他就會導去你預設的網站囉!向我這邊就是拿我的 facebook 來做示範。

結論

我透過這個方法幫我把 medium 的部落格網址重新導向,因為我想之後若是有獨立建立部落格的話網址會是一樣的,當有點粉絲的話至少他們認得的網址會是一樣的 😁。

參考

Route 53+靜態網址

繼續閱讀

Day21 - LINE Login 實作

前言

現在有規模的平台提供商基本上都會提供 Single Sign On (SSO)的登入機制,藉由他們的平台讓一般小網站可以讓使用者免密碼登入,雖然有很多種 Oauth2 的套件,不過我還是喜歡自己打 🤣,下面就開始嚕!

實作

views/建立一個line_login_auth.html,填入以下內容,主要是實作一個按鈕並透過 javascript 來互叫 api 並導向到 LINE 頁面

<html>
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <meta http-equiv="X-UA-Compatible" content="ie=edge" />
    <title>LINE Login</title>
  </head>
  <body>
    <button class="auth" onclick="auth()">LINE LOGIN</button>
  </body>
  <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.4.1/jquery.js"></script>
  <script>
    function auth() {
      $.ajax({
        url: 'https://YOUR_SERVERLESS_DOMAIN.amazonaws.com/dev/line/auth',
        method: 'POST',
        success: function(data) {
          window.location.replace(data.result);
        },
      });
    }
  </script>
</html>

接著我們在.env加入 LINE Login 的環境變數並輸入對應的參數

LINE_LOGIN_CLIENT_ID=
LINE_LOGIN_SECRET=
LINE_LOGIN_URI=https://YOUR_SERVERLESS_DOMAIN.amazonaws.com/dev/line/auth

最後就是我們最重要的部分了,實作 GET a& POST 的 api,這邊我先從 POST 講起,這邊主要是把環境變數組在網址中回傳給前端,這邊需要注意的是state他是在回傳回來的 JWT 需要解碼時所使用的,這邊我簡單打個字串,然而實際上會隨機產個變數,確保解碼的安全。

GET 則是負責處理從 LINE 回來的參數們,這邊我只用回傳回來的stateid_token解開,拿到裡面的使用者的參數,後續可以參照應用把資訊存下來,放入 session 並告知前端已登入。

from flask import request
from flask_restful import Resource
import requests
import webbrowser
import os
import jwt
import json


class LineLoginController(Resource):
	def get(self):
		r = requests.post(
			"https://api.line.me/oauth2/v2.1/token",
			data={
				"grant_type": "authorization_code",
				"code": request.args.get('CODE'),
				"redirect_uri": os.environ.get('LINE_LOGIN_URI'),
				"client_id": os.environ.get('LINE_LOGIN_CLIENT_ID'),
				"client_secret": os.environ.get('LINE_LOGIN_SECRET'),
			}, headers={"Content-Type": "application/x-www-form-urlencoded"})
		payload = json.loads(r.text)
		print(payload)
		token = payload.get("id_token")
		if token is None:
			return {'result': payload['error_description']}, 400

		state = request.args.get('state')
		token = token.encode()
		dt = jwt.decode(token, state, None, algorithms=['HS256'])
		if dt:
			return {'result': dt}, 200

	def post(self):
		r_uri = os.environ.get("LINE_LOGIN_URI")
		client = os.environ.get("LINE_LOGIN_CLIENT_ID")
		state = "nostate" # it will be random value
		uri = f"https://access.line.me/oauth2/v2.1/authorize?response_type=code&client_id={client}&redirect_uri={r_uri}&scope=profile%20openid%20email&state={state}"
		return {'result': uri}

JWT 解開的參數如下,sub就是 LINE 的唯一值 ID,一般拿到這個就可以知道是來自 LINE 的使用者了。

{
  "result": {
    "iss": "https://access.line.me",
    "sub": "Ud6ab866a67xxxxxxxxb12b0baffb8ac",
    "aud": "1622939248",
    "exp": 1569925548,
    "iat": 1569921948,
    "amr": ["linesso"],
    "name": "NiJia Lin",
    "picture": "https://profile.line-scdn.net/0hKvTocMuLFFlpFj9HpKdrDlVTGjxxxxxxxxx1YHACMOPRtEHmkWJVIKUyUJNkQWGT0X",
    "email": "loxxxxx09@gmail.com"
  }
}

最後別忘了要在api.py加入路由才會被導出去ㄛ

from controller.line_login_controller import LineLoginController
api.add_resource(LineLoginController, '/line/auth')

結論

在實作的時候不知道為什麼一直不能讓 python 去幫我把用戶導去 LINE 認證的頁面,我記得之前寫 Ruby 可以啊(?),最後只好讓前端去幫我把使用者導出去,這邊就帶大家做到這嚕!

繼續閱讀

Day17 - 看一下自己寫的東西都去哪了

前言

用 Serverless 用得這麼爽,也是時候來看一下他的資源在哪,距離我上次自己手動上傳 python 檔已經是 N 個月之前的事了(遠望),當時也沒用過什麼Api Gateway相關的服務,以下就帶大家來介紹一下嚕!

介紹

CloudFormation

CloudFormation 是一個 AWS 所提供的 JSON-base 服務,主要是用來讓使用者能夠快速建立 AWS 的服務。

這邊也不用擔心設定的問題,Serverless 再 deploy 的過程中會幫忙 CloudFormation 的 json 檔

透過 CloudFormation 建立 JSON-based 的 template 你可以快速建立所需要的資源堆疊(stack)。

按下Template後如下圖所示,他會顯示你已經有建立的服務 Map,整個線牽起來看起來就很爽 XD

Api Gateway

Serverless 建立過程中也會透過 CloudFormation 幫忙建立 Api Gateway,因為我們是用 WSGI,所以只會看到兩個ANY的路由。 點進去後就可以看到 Client 是怎麼進出的,最右邊是打到 AWS Lambda 上,可以點選上面的字進入 Lambda 所在地。

Lambda

點選進來之後可以看到 Lambda 接了什麼服務,以我到目前的程式就會有API GatewaySQS以及預設的CloudWatch(都是透過這個來看 log) 接著往下會看到之前設定的環境變數以及STAGE,這些都是托Serverless的福免去這些麻煩的設定

S3

Serverless 在過程中會在 S3 幫忙建立一個 Bucket,並在後面加個 hash key 以免 bucket 重複。

Cloud Watch Log

在開始測試後 AWS 會幫忙在這個地方輸出 Log,

Serverless deploy 紀錄

這邊使用 Serverless deploy --verbose 就可以看到所有部署中的基本資訊了

首先因為我們有使用.env,所以在一開始時會先設定環境變數,接著就是把相依套件的東西都放進去,再去啟動 CloudFormation


接著會建立一個 S3 的 Bucket,將程式透過 CloudFormation 處理成 zip的檔案格式並上傳到 S3 上面


接著就會部署到 Lambda 以及 Api Gateway 上,並做對應 CloudFormation JSON 檔的設定


在最後部署完之後就可以看到所有的基本資訊,物件名稱、部署階段、區域、網域以及 Function 們(因為 Lambda 是 Function-base 的服務)等等的基本資訊都會在此

結論

以目前的架構基本上到這麼基本資訊都顯示出來了,若是有使用像是Route 53CloudFront等等的服務它就會顯示在這邊了。雖然說 CloudFormation 在設定上已經很方便了,但不得不說 Serverless 真的幫忙做了很多事,讓開發者又更能專注在打 Code 上了~

參考

使用 CloudFormation 快速部署 AWS 資源

繼續閱讀

Day4 - 認識與使用 S3 容器

前言

Amazon Simple Storage Service(簡稱 AWS S3)是 AWS 的一個線上儲存服務,用戶能夠輕易把檔案儲存到網路伺服器上,可能有些朋友會把它當成雲端硬碟看待,但其實還能像是傳靜態檔案上去,若有寫前端框架的朋友通常都會需要把程式碼打包成靜態檔案再部署,然而這邊把他打包送上去後,S3 會給一個名為 Object Url 的網址,可以透過這個網址去執行網頁裡面的內容(如 AJAX、Axios...),並可以透過 cloudfont 去弄成 CDN(扯遠了),簡單說他還有很多不一樣的功能應用等著大家去用~

因為 serverless 只能放關於 API 的程式碼,因此我們需要把 html 靜態檔案放在 S3 裡,

接下來就來建立一個公開的 S3 容器,這邊就不會提到權限如何控管哦!

建立一個公開的 S3 容器

建立一個名為2019-it-30-bucket的容器,地區就選與 Lambda 同樣的地區,直接按下左下角的create來建立。

建立完會像這樣 接著點進去後在點到第三個選項會看到 Block of public access 是啟動的狀態,因為我們接下來需要讓我們的頁面可以外部使用 就把 check box 的按掉,在按下 Save 要輸入confirm就修改完成嚕 接著一樣點到第三個個選項,選到Access Control List,看到Access for bucket owner這個選項的Canonical ID,選項都全部打勾之後再來調整,這樣之後的 HTML 檔案外面就看得到了。

測試

接著上傳一個index.html的檔案來測試

<html>
<h1>Hello world</h1>
</html>

上傳後下拉式選單選擇public read的選項,因為一個檔案在 S3 就算是一個 Object,所以一定要讓它能對外,然後按下左下的 Upload

成功後點進這個檔案,並按下方的Object URL,看到 Hello World 的話就代表成功囉,這時可以開個無痕測一次,確認一下沒有錯誤 😃

參考

AWS S3 wiki

繼續閱讀