tornado 之authenticated和session 簡單登陸

1.登陸檢查(裝飾器的使用)html

咱們登陸的時候須要驗證,可是若是有不少地方須要驗證,這個時候就會出現不少重複代碼的狀況,這個時候咱們須要一個不改變函數運行,又能給函數加上驗證過程方法,很明顯,咱們能夠使用裝飾器來達到這個功能,代碼以下:web

def auth(fun):
    def wrapper(self,*args,**kwargs):
        id = self.get_secure_cookie('ID')
        if id:
            return fun(self,*args,**kwargs)
        else:
            self.redirect('/login')
    return wrapper

#定義好裝飾器以後,就能夠直接去修飾須要驗證的方法  redis

class IndexHandler(BaseHandler):
    @auth
    def get(self):
        self.write('登陸成功---index')

使用裝飾器能夠很方便咱們去作登陸檢查,能夠節省出大量的代碼,增長程序的可讀性和程序總體的美觀。數據庫

2.authenticated瀏覽器

雖然咱們本身能夠作這個登陸檢查,可是在tornado內部給咱們提供了一個內置的裝飾器`authenticated`這個能夠幫咱們自動的進行登陸驗證,`authenticated`能夠省去咱們本身重複造輪子的過程,可是在使用的時候須要注意幾點:安全

# Application中添加配置
login_url='/login',

# 重寫 get_current_user 方法
class BaseHandler(tornado.web.RequestHandler):
    def get_current_user(self):
        current_user = self.get_secure_cookie('ID')
        if current_user:
            return current_user
        return None
# 裝飾須要驗證的方法      
@authenticated     

有些時候咱們須要跳轉到以前的頁面怎麼作呢?當咱們使用`authenticated`的時候咱們能夠十分方便的作這件事情。咱們觀察跳轉以後的url就能夠發現,若是是使用`authenticated`裝飾器裝飾以後,而跳轉到登陸頁面以後,在登陸頁面的url中,能夠看到最後面會添加上一個next參數,這個就是咱們剛纔跳轉的路由,經過這個參數,咱們就能夠很方便的跳轉回以前的的路由,具體實現以下:服務器

class LoginHandler(BaseHandler):
    def get(self):
        nextname = self.get_argument('next','')
        self.render('authenticated.html',nextname=nextname)
    def post(self):
        nextname = self.get_argument('next', '')
        username = self.get_argument('name','')
        username = User.by_name(username)
        passwd = self.get_argument('password', '')
        print(username)
        if username and username[0].password == passwd:
            self.set_secure_cookie('ID',username[0].username,max_age=100)
            self.redirect(nextname)
        else:
            self.render('authenticated.html',nextname=nextname)

頁面代碼作以下的改變就行:cookie

<form method="post" action="/login?next={{nextname}}">
    <p>用戶名<br><input type="text" name="name"></p>
    <p>密碼<br><input type="text" name="password"></p>
    <input type="submit">
</form>

配合使用模板的傳參,能夠很方便的進行跳轉。session

3.sessionapp

cookie中不能存放存放用戶的敏感信息,那麼cookie裏面就只能存放一些隨機的字符串,可是若是這樣的話,那麼服務器端又怎樣知道是那個用戶呢?

咱們能夠創建一個會話來作這件事情,這個會話裏面會存儲隨機字符串和能夠惟一肯定用戶的信息。

因爲tornado沒有內置session模塊,因此使用pycket這個模塊中封裝好的session模塊來,要想使用首先要安裝:

pip install pyckey
pip install redis

安裝好以後就能夠使用了,使用很簡單,注意一下幾點:

from pycket.session import SessionMixin

# 1.在Application添加 pycket 的配置
pycket={
  'engine': 'redis',
  'storage': {
    'host': 'localhost',
    'port': 6379,
    'db_sessions': 5,
    'db_notifications': 11,
    'max_connections': 2**31,
  },
  'cookies': {
    'expires_days': 30,
    'max_age': 100
  },
},

# 2.改 self.set_secure_cookie 爲 self.session.set
# self.set_secure_cookie('ID',username[0].username,max_age=100)
self.session.set('user',username[0].username)

# 3.改 self.get_secure_cookie 爲 self.session.get
# current_user = self.get_secure_cookie('ID')
current_user = self.session.get('user')

以上就能夠使用`session`了,這個`session`的工做原理是以下:

1. 使用`set`方法,爲輸入的用戶信息生成一串隨機字符串
2. 將這個字符串和對應的用戶信息作成鍵值對,放到`redis`數據庫中
3. 將字符串處理以後放入到`cookie`中,發送給瀏覽器
4. 瀏覽器請求時將`cookie`中的信息發送到服務器,`tornado`接受到以後解析出來,去`redis`查找,找到就驗證成功

使用`session`有以下好處:

1. 能夠不要在`cookie`中存放敏感信息
2. 減小數據傳輸須要的時間
3. 減小加密解密的時間

`session`的使用很簡單,可是安全性會有一個很大的提高,所以使用很是多,必定要掌握使用方法。

4.跨站防僞造請求的防範

跨站僞造請求(Cross-site request forgery)](https://en.wikipedia.org/wiki/Cross-site_request_forgery), 簡稱爲 `XSRF`,是個性化 Web 應用中常見的一個安全問題。前面的連接也詳細講述了` XSRF `攻擊的實現方式。

當前防範` XSRF` 的一種通用的方法,是對每個用戶都記錄一個沒法預知的` cookie `數據,而後要求全部提交的請求中都必須帶有這個` cookie `數據。若是此數據不匹配 ,那麼這個請求就多是被僞造的。

`Tornado `有內建的 `XSRF `的防範機制,要使用此機制,只須要在模板中添加以下代碼:

<form method="post" action="/login?next={{nextname}}">
    {% module xsrf_form_html() %}   <!--添加這行代碼就能夠了-->
    <p>用戶名<br><input type="text" name="name"></p>
    <p>密碼<br><input type="text" name="password"></p>
    <input type="submit">
相關文章
相關標籤/搜索