最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

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

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

Nginx配置

Ngnix,一個高性能的web服務器,毫無疑問它是當下的寵兒。卓越的性能,靈活可擴展,在服務器領域里攻城拔寨,征戰(zhàn)天下。

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

粗略的處理,在后端程序可以做過濾,渲染頁面的時候,在視圖邏輯里面驗證用戶登錄,然后返回對應的頁面。例如下面的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

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

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

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

為了解決這個問題,nginx提供的 XSendfile功能,簡而言之就是用 internal 指令。該指令表示只接受內(nèi)部的請求,即后端轉(zhuǎn)發(fā)過來的請求。后端的視圖邏輯中,需要明確的寫入X-Accel-Redirect這個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)過這樣的處理,就能將靜態(tài)資源進行重定向。這樣的用法還是比較常見的,很多下載服務器可以通過這樣的手段針對用戶的權限做下載處理。

Flask

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

項目結構

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/;

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

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')

# 用戶上傳的文件視圖處理,在此處返回請求給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)

簡單部署

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

相關文章

最新評論

巍山| 高安市| 大英县| 金秀| 乐业县| 华亭县| 余江县| 龙门县| 天门市| 荆州市| 抚州市| 保定市| 水富县| 达孜县| 金堂县| 怀化市| 湖州市| 浦东新区| 广元市| 郑州市| 阿城市| 梅州市| 左云县| 灵山县| 龙胜| 高州市| 岳普湖县| 治多县| 宁波市| 旬邑县| 安丘市| 姚安县| 高尔夫| 沁源县| 克山县| 广丰县| 南开区| 青龙| 安国市| 新平| 清水县|