我使用 MKdocs 創建一個非常敏感的檔案,??我不希望它可以安全地在線獲得。
我的專案是:
- [V] 在服務器上創建加密卷(我使用了veracrypt,cli和python兼容)
- [V] 制作簡單頁面求密鑰解密
- [V]解密卷
- [X] 燒瓶上的服務站點
- [V] 檢測會話關閉并再次加密卷
(這樣服務器上沒有持久的清除資料)
檔案只能在本地編輯、加密并同步到服務器。
現在,我在燒瓶步驟的服務站點上被阻止,因為 MKdocs 站點的結構如下:
├── 404.html
├── documentation
│ ├── Folder 1
│ │ ├── Sub folder 1
│ │ │ └── index.html
│ │ └── Sub Folder 2
│ │ └── index.html
│ ├── Folder 2
├── css
│ └── ...
├── fonts
│ └── ...
├── img
│ └── ...
├── index.html
├── js
│ └── ...
├── search
│ └── ...
└── ...
我試圖把這個內容放在下面,然后用燒瓶./static/site/替換所有本地href和鏈接src
{{ url_for('static', filename='site/[original_content]) }}
但據我所知,它不能像靜態呼叫一樣作業
app.send_static_file('site/index.html')
因為沒有替換{{ .. }}內容(和我預料的這個問題,是靜態頁面)。
問題: 有沒有辦法使用燒瓶為具有這樣“復雜”結構的靜態站點提供服務?
更多而非必要的資訊,劇透不是問題的一部分!:
只要我能接受任何關于如何以不同方式做整個事情的建議,現在,我想實作它。
我想到的其他解決方案:
- 使用 nginx 提供靜態網站,在一個空檔案夾上,具有先前機制的燒瓶將解密該卷。我不知道如何檢測結束 nginx 會話以再次加密。
- 將所有結構壓縮在一個大 HTML 檔案中。這太棒了,但我真的浪費了太多時間搜索和嘗試,但是......不是幸運的研究。(但將是我推薦的解決方案
uj5u.com熱心網友回復:
我們可以將 MkDocs 的渲染 HTML 頁面視為簡單的 Flask 模板。所以我們所要做的就是創建一個 Flask 端點,它首先進行權限檢查,然后基于 URL,提供呈現的 MkDocs HTML 檔案或相關的靜態檔案。
讓我們呼叫我們的新端點bridge。首先,將 MkDocssite目錄中的所有內容放到 Flask 的templates/bridge目錄中。我的示例 MkDocs 樹如下所示:
$ tree templates/bridge
templates/bridge
├── 404.html
├── css
│ ├── base.css
│ ├── bootstrap.min.css
│ └── font-awesome.min.css
├── dir1
│ ├── sub1
│ │ └── index.html
│ └── sub2
│ └── index.html
├── dir2
│ ├── sub1
│ │ └── index.html
│ └── sub2
│ └── index.html
├── fonts
│ ├── fontawesome-webfont.eot
│ ├── fontawesome-webfont.svg
│ ├── fontawesome-webfont.ttf
│ ├── fontawesome-webfont.woff
│ └── fontawesome-webfont.woff2
├── img
│ ├── favicon.ico
│ └── grid.png
├── index.html
├── js
│ ├── base.js
│ ├── bootstrap.min.js
│ └── jquery-1.10.2.min.js
├── search
│ ├── lunr.js
│ ├── main.js
│ ├── search_index.json
│ └── worker.js
├── sitemap.xml
└── sitemap.xml.gz
還有我們新的 Flaskbridge端點:
from flask import Flask, render_template, send_from_directory
app = Flask(__name__)
@app.route('/bridge/')
@app.route('/bridge/<path:p1>/')
@app.route('/bridge/<path:p1>/<path:p2>/')
@app.route('/bridge/<path:p1>/<path:p2>/<path:p3>/')
def bridge(p1=None, p2=None, p3=None):
# Permissions checking...
# Serve MkDocs's static files requested from CSS files
if p1 == 'css' and p2 in ('img', 'fonts'):
# CSS fix, e.g. /bridge/css/img/example.png -> /bridge/img/example.png
return send_from_directory(f'templates/bridge/{p2}/', p3)
# Serve MkDocs's static files
if p1 in ('css', 'js', 'fonts', 'search'):
return send_from_directory(f'templates/bridge/{p1}/', p2)
# Serve rendered MkDocs HTML files
if p3 != None:
template = f'bridge/{p1}/{p2}/{p3}/index.html'
elif p2 != None:
template = f'bridge/{p1}/{p2}/index.html'
elif p1 != None:
template = f'bridge/{p1}/index.html'
else:
template = 'bridge/index.html'
return render_template(template)
如您所見,我們創建了幾個路徑定義。由于 MkDocs 在任何地方都使用相對路徑,因此dir1/sub1/MkDocs 中的 URL 路徑將變為https://yoursite.com/bridge/dir1/sub1/我們可以使用此 URL 路由方案捕獲它們,并且 URL 部分將進入p1我們將用于提供相應內容的路徑變數p2。p3
有兩種型別的內容:靜態檔案(例如 CSS 檔案或影像)和 HTML 內容檔案。靜態檔案將位于css, js, images, fonts, 等目錄中,因此當p1等于其中之一時,我們使用 Flask 的send_from_directory函式來提供它們。從 CSS 檔案參考的靜態檔案需要進行特定處理,因為 MkDocs 在那里也使用相對路徑。
而對于渲染的index.html檔案,我們只需要根據路徑確定嵌套級別,并將選定的index.html檔案作為普通的 Flask 模板回傳。由于 MkDocs 使用相對 URL,我們不必修改呈現的 HTML 檔案中的任何內容,每個 URL 都會收到/bridge/前綴,因此我們可以使用bridge端點為它們提供服務。
您應該在開始時進行權限檢查bridge(或作為裝飾者,取決于您的解決方案)。如果您有更深入的嵌套內容,您可能需要添加p4和/或p5路徑變數,但這是對我的示例的直接擴展。
注意:404 錯誤頁面也將由 Flask 提供。
uj5u.com熱心網友回復:
我的代碼有很多問題,我/bridge/index.html在解密后重定向到,從那里點擊的任何內容都以 /bridge 開頭/index.html/resource/p1/p2/etc..
之后我不得不重新考慮 p1、p2 和其他人在哪里,我發現的解決方案完全基于 Dauros 解決方案,我真正喜歡的是:
@app.route('/<path:p1>/')
@app.route('/<path:p1>/<path:p2>/')
@app.route('/<path:p1>/<path:p2>/<path:p3>/')
@app.route('/<path:p1>/<path:p2>/<path:p3>/<path:p4>/')
@app.route('/<path:p1>/<path:p2>/<path:p3>/<path:p4>/<path:p5>/')
@app.route('/<path:p1>/<path:p2>/<path:p3>/<path:p4>/<path:p5>/<path:p6>/')
def bridge(p1=None, p2=None, p3=None, p4=None, p5=None, p6=None):
# Permissions checking...
# I'm planning on using basic auth from nginx to even try to show a page
resource = '/'.join([p for p in (p1,p2,p3,p4,p5,p6) if p])
the_file = resource.split('/')[-1]
the_path = '/'.join(resource.split('/')[:-1])
if p1 in ('css', 'fonts', 'img', 'js', 'search'):
return send_from_directory(f'templates/bridge/{the_path}/', the_file)
else:
template = f'bridge/{resource}/index.html'
return render_template(template)
@app.route('/', methods=HTTP_METHODS)
def home():
method = request.method
if method == "GET":
# TO BE CHANGED, checking if volume is already decrypted.
if os.path.exists(f"{BASE_FODLER}/locked"):
# decrypt page
resp = make_response(render_template('decrypt.html'))
return resp
else:
template = 'bridge/index.html'
return render_template(template)
elif method == "POST":
if 'password' in request.form:
decrypt_key = request.form['password']
# decryption omitted
template = 'bridge/index.html'
return render_template(template)
else:
return not_allowed_ans()
else:
return not_allowed_ans()
return SendOk()
如您所見,從底部開始,template = 'bridge/index.html'然后return render_template(template)將橋接站點置于根目錄下,mystime.com/這意味著所有路由都必須是根目錄。
任何“鏈接”都將是:mysite.com/folder_1/sub_folder_1/index.html
之后我讓我在未來添加 pX 變得簡單(如果使用動態 PX 的單一路由會很好,但是,這對于靜態檔案來說已經足夠了!)
轉載請註明出處,本文鏈接:https://www.uj5u.com/qianduan/419772.html
標籤:
上一篇:燒瓶運行未找到模塊匯入但可與gunicorn一起使用
下一篇:SQL排序和排序表
