欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

Python的Flask框架及Nginx實(shí)現(xiàn)靜態(tài)文件訪問限制功能

 更新時(shí)間:2016年06月27日 17:16:09   作者:人世間  
這篇文章主要介紹了Python的Flask框架及Nginx實(shí)現(xiàn)靜態(tài)文件訪問限制功能,Nginx方面利用到了自帶的XSendfile,需要的朋友可以參考下

Nginx配置

Ngnix,一個(gè)高性能的web服務(wù)器,毫無(wú)疑問它是當(dāng)下的寵兒。卓越的性能,靈活可擴(kuò)展,在服務(wù)器領(lǐng)域里攻城拔寨,征戰(zhàn)天下。

靜態(tài)文件對(duì)于大多數(shù)website是不可或缺的一部分。使用Nginx來(lái)處理靜態(tài)文件也是常見的方式。然而,一些靜態(tài)文件,我們并不像任何情況下都公開給任何用戶。例如一些提供給用戶下載的文件,一些用戶上傳的涉及用戶隱私的圖片等。我們我希望用戶登錄的情況下可以訪問,未登錄的用戶則不可見。

粗略的處理,在后端程序可以做過(guò)濾,渲染頁(yè)面的時(shí)候,在視圖邏輯里面驗(yàn)證用戶登錄,然后返回對(duì)應(yīng)的頁(yè)面。例如下面的flask代碼(偽代碼)

@app.router('/user/idcard'):
def user_idcard_page():
 if user is login:
  return '<img src="/upload/user/xxx.png'>"
 else:
  reutrn '<p>Pemission Denied<p>', 403

可是這樣的處理,還有一個(gè)問題,靜態(tài)文件是交給 nginx 處理的,如果hacker找到了文件的絕對(duì)地址,直接訪問 http://www.example.com/upload/user/xxx.png也是可以的。恰巧這些文件又涉及用戶隱私,比如用戶上傳的身份證照片。那么碼農(nóng)可不希望第二天媒體報(bào)道,知名網(wǎng)站XXX存在漏洞,Hacker獲取了用戶身份證等信息。

為了做這樣的限制,可以借助 Nginx 的一個(gè)小功能----XSendfile。 其原理也比較簡(jiǎn)單,大概就是使用了請(qǐng)求重定向。

我們知道,如果用Nginx做服務(wù)器前端的反向代理,一個(gè)請(qǐng)求進(jìn)來(lái),nginx先補(bǔ)捉到,然后再根據(jù)規(guī)則轉(zhuǎn)發(fā)給后端的程序處理,或者直接處理返回。前者處理一些動(dòng)態(tài)邏輯,后者多是處理靜態(tài)文件。因此上面那個(gè)例子中,直接訪問靜態(tài)文件的絕對(duì)地址,Nginx就直接返回了,并沒有調(diào)用后端的 user_idcard_page做邏輯限制。

為了解決這個(gè)問題,nginx提供的 XSendfile功能,簡(jiǎn)而言之就是用 internal 指令。該指令表示只接受內(nèi)部的請(qǐng)求,即后端轉(zhuǎn)發(fā)過(guò)來(lái)的請(qǐng)求。后端的視圖邏輯中,需要明確的寫入X-Accel-Redirect這個(gè)headers信息。

偽代碼如下:

location /upload/(.*) {
  alias /vagrant/;
  internal;
}

@app.router('upload/<filename>')
@login_required
def upload_file(filename):
 response = make_response()
 response['Content-Type'] = 'application/png'
 response['X-Accel-Redirect'] = '/vagrant/upload/%s' % filename
 return response

經(jīng)過(guò)這樣的處理,就能將靜態(tài)資源進(jìn)行重定向。這樣的用法還是比較常見的,很多下載服務(wù)器可以通過(guò)這樣的手段針對(duì)用戶的權(quán)限做下載處理。

Flask

Flask是我喜歡的web框架,F(xiàn)lask甚至實(shí)現(xiàn)了一個(gè) sendfile的方法,比上面的做法還簡(jiǎn)單。我用vagrant作了一個(gè)虛擬機(jī),用Flask實(shí)現(xiàn)了上面的需求,具體代碼如下:

項(xiàng)目結(jié)構(gòu)

project struct

project
 app.py
 templates
 static
 0.jpeg
 upload
 0.jpeg

nginx的配置 nginx conf

web.conf

server {
  listen 80 default_server;

  # server_name localhost;
  server_name 192.168.33.10;
  location / {
    proxy_pass http://127.0.0.1:8888;
    proxy_redirect off;
    proxy_set_header Host $host:8888;
    proxy_set_header X-Real-IP $remote_addr;
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
  }
  # 正常的靜態(tài)文件
  location /static/(.*) {
    root /vagrant/;

  }
  # 用戶上傳的文件,需要做權(quán)限限制
  location /upload/(.*) {
    alias /vagrant/;
    internal;    # 只接受內(nèi)部請(qǐng)求的指令
  }
}

Flask 代碼

app.py

from functools import wraps
from flask import Flask, render_template, redirect, url_for, session, send_file

app = Flask(__name__)

app.config['SECRET_KEY'] = 'you never guess'

def login_required(f):
 @wraps(f)
 def decorated_function(*args, **kwargs):
  if not session.get('login'):
   return redirect(url_for('login', next=request.url))
  return f(*args, **kwargs)
 return decorated_function

@app.route('/')
def index():
 return 'index'


@app.route('/user')
@login_required
def user():

 return render_template('upload.html')

# 用戶上傳的文件視圖處理,在此處返回請(qǐng)求給nginx
@app.route('/upload/<filename>')
@login_required
def upload(filename):

 return send_file('upload/{}'.format(filename))


@app.route('/login')
def login():
 session['login'] = True
 return 'log in'

@app.route('/logout')
def logout():
 session['login'] = False
 return 'log out'


if __name__ == '__main__':
 app.run(debug=True)

簡(jiǎn)單部署

gunicorn -w4 -b0.0.0.0:8888 app:app --access-logfile access.log --error-logfile error.log

相關(guān)文章

  • Python 共享變量加鎖、釋放詳解

    Python 共享變量加鎖、釋放詳解

    這篇文章主要介紹了Python 共享變量加鎖、釋放詳解,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下
    2019-08-08
  • Python中統(tǒng)計(jì)函數(shù)運(yùn)行耗時(shí)的方法

    Python中統(tǒng)計(jì)函數(shù)運(yùn)行耗時(shí)的方法

    這篇文章主要介紹了Python中統(tǒng)計(jì)函數(shù)運(yùn)行耗時(shí)的方法,涉及Python時(shí)間操作的相關(guān)技巧,非常簡(jiǎn)單實(shí)用,需要的朋友可以參考下
    2015-05-05
  • 基于Python socket的端口掃描程序?qū)嵗a

    基于Python socket的端口掃描程序?qū)嵗a

    這篇文章主要介紹了基于Python socket的端口掃描程序?qū)嵗a,分享了相關(guān)代碼示例,小編覺得還是挺不錯(cuò)的,具有一定借鑒價(jià)值,需要的朋友可以參考下
    2018-02-02
  • 教你用Python寫一個(gè)水果忍者小游戲

    教你用Python寫一個(gè)水果忍者小游戲

    水果忍者游戲,又稱切水果游戲,玩法簡(jiǎn)單,水果忍者游戲在兒童中很受歡迎,下面這篇文章主要給大家介紹了關(guān)于如何利用Python寫一個(gè)水果忍者小游戲的相關(guān)資料,需要的朋友可以參考下
    2022-03-03
  • Django中的CACHE_BACKEND參數(shù)和站點(diǎn)級(jí)Cache設(shè)置

    Django中的CACHE_BACKEND參數(shù)和站點(diǎn)級(jí)Cache設(shè)置

    這篇文章主要介紹了Django中的CACHE_BACKEND參數(shù)和站點(diǎn)級(jí)Cache設(shè)置,Python是最具人氣的Python web框架,需要的朋友可以參考下
    2015-07-07
  • Python元類與迭代器生成器案例詳解

    Python元類與迭代器生成器案例詳解

    這篇文章主要介紹了Python元類與迭代器生成器案例詳解,本篇文章通過(guò)簡(jiǎn)要的案例,講解了該項(xiàng)技術(shù)的了解與使用,以下就是詳細(xì)內(nèi)容,需要的朋友可以參考下
    2021-08-08
  • Windows64x下VScode下載過(guò)程

    Windows64x下VScode下載過(guò)程

    這篇文章主要介紹了Windows64x下VScode下載,本文通過(guò)圖文并茂的形式給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2022-09-09
  • python UDF 實(shí)現(xiàn)對(duì)csv批量md5加密操作

    python UDF 實(shí)現(xiàn)對(duì)csv批量md5加密操作

    這篇文章主要介紹了python UDF 實(shí)現(xiàn)對(duì)csv批量md5加密操作,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧
    2021-01-01
  • Python利用字節(jié)串或字節(jié)數(shù)組來(lái)加載和保存PDF文檔

    Python利用字節(jié)串或字節(jié)數(shù)組來(lái)加載和保存PDF文檔

    處理PDF文件的可以直接讀取和寫入文件系統(tǒng)中的PDF文件,然而,通過(guò)字節(jié)串(byte string)或字節(jié)數(shù)組(byte array)來(lái)加載和保存PDF文檔在某些情況下更高效,本文將介紹如何使用Python通過(guò)字節(jié)串或字節(jié)數(shù)組來(lái)加載和保存PDF文檔,需要的朋友可以參考下
    2024-09-09
  • Flask框架信號(hào)用法實(shí)例分析

    Flask框架信號(hào)用法實(shí)例分析

    這篇文章主要介紹了Flask框架信號(hào)用法,結(jié)合實(shí)例形式分析了Blinker的安裝及信號(hào)的接收等相關(guān)操作技巧,需要的朋友可以參考下
    2018-07-07

最新評(píng)論