SpringCloud+Tornado基于jwt實現(xiàn)請求安全校驗功能
項目背景
在實際項目中,Tornado項目作為一個微服務納入SpringCloud體系,該過程中涉及到Tornado與Spring體系的安全驗證,也就是權(quán)限調(diào)用校驗,在該項目中Tornado是通過SpringCloud中的Feign調(diào)用的,經(jīng)過一系列實驗,最后選用jwt來實現(xiàn)這個權(quán)限效驗的過程。
實現(xiàn)思路
用戶進行登陸認證(后臺微服務),認證成功后調(diào)用Tornado項目的認證接口生成token,該值返回到后臺微服務保存在會話中,下一次請求時帶上該token值讓服務器進行校驗,校驗成功則返回正常的響應,否則返回錯誤信息。
項目結(jié)構(gòu)

common - authServer.py是認證接口 common - basicServer.py是示例接口 handlers - baseHandler.py中放了兩種校驗方式,會在basicServer.py的調(diào)用示例中貼出 utils - jwtUtils.py是生成與校驗token的 utils - responseUtils.py是返回結(jié)果工具類
具體實現(xiàn)
jwtUtils.py
# -*- coding:utf-8 -*-
import jwt
import datetime
from jwt import exceptions
from utils.responseUtils import JsonUtils
JWT_SALT = '1qazxdr5'
def create_token(payload, timeout=12):
"""
創(chuàng)建token
:param payload: 例如:{'user_id':1,'username':'xxx@xxx.xx'}用戶信息
:param timeout: token的過期時間,默認20分鐘
:return:
"""
headers = {
'typ': 'jwt',
'alg': 'HS256'
}
payload['exp'] = datetime.datetime.utcnow() + datetime.timedelta(minutes=timeout)
result = jwt.encode(payload=payload, key=JWT_SALT, algorithm="HS256", headers=headers).decode('utf-8')
return result
def parse_payload(token):
"""
對token進行校驗并獲取payload
:param token:
:return:
"""
try:
verified_payload = jwt.decode(token, JWT_SALT, True)
print(verified_payload)
return JsonUtils.success('認證通過')
except exceptions.ExpiredSignatureError:
return JsonUtils.noAuth('token已失效')
except jwt.DecodeError:
return JsonUtils.noAuth('token認證失敗')
except jwt.InvalidTokenError:
return JsonUtils.noAuth('非法的token')
baseHandler.py
# -*- coding:utf-8 -*-
import functools
import json
import tornado.web
from utils import jwtUtils
from utils.responseUtils import JsonUtils
# 方式一:authenticated 裝飾器
def authenticated(method):
@functools.wraps(method)
def wrapper(self, *args, **kwargs):
"""
這里調(diào)用的是 current_user 的 get 方法(property裝飾),
"""
# 通過token請求頭傳遞token
head = self.request.headers
token = head.get("token", "")
if not token:
self.write(JsonUtils.noAuth("未獲取到token請求頭"))
self.set_header('Content-Type', 'application/json')
return
result = json.loads(jwtUtils.parse_payload(token)) # 將json解碼
print(result)
token_msg = json.dumps(result)
if result['sta'] != '00':
self.write(token_msg)
self.set_header('Content-Type', 'application/json')
return
return method(self, *args, **kwargs)
return wrapper
# 方式二:進行預設 繼承tornado的RequestHandler
class BaseHandler(tornado.web.RequestHandler):
def prepare(self):
super(BaseHandler, self).prepare()
def set_default_headers(self):
super().set_default_headers()
# 進行token校驗,繼承上面的BaseHandler
class TokenHandler(BaseHandler):
def prepare(self):
# 通過token請求頭傳遞token
head = self.request.headers
token = head.get("token","")
if not token:
self.authMsg = json.dumps(JsonUtils.noAuth("未獲取到token請求頭"))
result = json.loads(jwtUtils.parse_payload(token)) # 將json解碼
print(result)
if result['sta'] != '00':
self.isAuth = False
else:
self.isAuth = True
self.authMsg = json.dumps(result)
authServer.py
import tornado.web
from utils import jwtUtils
from utils.responseUtils import JsonUtils
class authHandler(tornado.web.RequestHandler):
def post(self, *args, **kwargs):
"""
安全認證接口
:param args:
:param kwargs:
:return:
"""
username = self.get_argument("username")
print("authHandler:" + username)
if not username:
self.write(JsonUtils.error("參數(shù)異常"))
else:
token = jwtUtils.create_token({"username": username})
print("token:" + token)
self.write(JsonUtils.success(token))
self.set_header('Content-Type', 'application/json')
basicServer.py
import tornado.web
import json
from pandas.core.frame import DataFrame
from handlers import baseHandler
from utils.responseUtils import JsonUtils
from handlers.baseHandler import authenticated
class StringHandler(baseHandler.TokenHandler, tornado.web.RequestHandler):
"""
*** TokenHandler驗證,對應baseHandler.py中的方式二 ***
"""
def get(self):
username = self.get_argument('username', 'Hello')
# 權(quán)限認證通過
if self.isAuth:
self.write(JsonUtils.success(username))
else:
self.write(self.authMsg))
self.set_header('Content-Type', 'application/json')
class TestHandler(tornado.web.RequestHandler):
"""
*** authenticated驗證,對應baseHandler.py中的方式一 ***
"""
@authenticated
def post(self):
username = self.get_argument('username', 'Hello')
self.write(JsonUtils.success(username))
self.set_header('Content-Type', 'application/json')
responseUtils.py
from tornado.escape import json_encode, utf8
class JsonUtils(object):
@staticmethod
def success(response):
"""
正確返回
:param response: 返回結(jié)果
:return: string, {"message": "ok", "sta": "00", "data": }
"""
return json_encode({"message": "ok", "sta": "00", "data": response})
@staticmethod
def info(message):
"""
提示返回
:param message: 提示信息
:return: string,
"""
return json_encode({"message": str(message), "sta": "99001", "data": None})
@staticmethod
def error(message):
"""
錯誤返回
:param message: 錯誤信息
:return: string,
"""
return json_encode({"message": str(message), "sta": "9999", "data": None})
@staticmethod
def noAuth(message):
"""
無權(quán)限返回
:param message: 錯誤信息
:return: string,
"""
return json_encode({"message": str(message), "sta": "403", "data": None})
下面是一些調(diào)用的結(jié)果圖示:



.end
到此這篇關于SpringCloud+Tornado基于jwt實現(xiàn)請求安全校驗的文章就介紹到這了,更多相關SpringCloud+Tornado實現(xiàn)請求安全校驗內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!
相關文章
Java如果在try里面執(zhí)行return還會不會執(zhí)行finally
這篇文章主要介紹了Java如果在try里面執(zhí)行return,那么還會不會執(zhí)行finally,本文給大家介紹的非常詳細,對大家的學習或工作具有一定的參考借鑒價值,需要的朋友可以參考下2021-01-01
Java向MySQL添加中文數(shù)據(jù)數(shù)據(jù)庫顯示亂碼的解決方案
在用springboot做項目時,由于重新安裝了本地Mysql數(shù)據(jù)庫(5.7版本)在前臺向數(shù)據(jù)庫插入和更新數(shù)據(jù)可的時候,涉及中文的時候在數(shù)據(jù)庫一直顯示異常,所以本文給大家介紹了相關的解決方案,需要的朋友可以參考下2024-02-02
深入探究一下Java中不同的線程間數(shù)據(jù)通信方式
這篇文章主要來和大家一起深入探究一下Java中不同的線程間數(shù)據(jù)通信方式,文中的示例代碼講解詳細,具有一定的借鑒價值,需要的可以參考一下2023-04-04
SpringBoot中的ApplicationListener事件監(jiān)聽器使用詳解
這篇文章主要介紹了SpringBoot中的ApplicationListener事件監(jiān)聽器使用詳解,ApplicationListener是應用程序的事件監(jiān)聽器,繼承自java.util.EventListener標準接口,采用觀察者設計模式,需要的朋友可以參考下2023-11-11
在SpringBoot框架下實現(xiàn)Excel導入導出的方法詳解
SpringBoot是由Pivotal團隊提供的全新框架,其設計目的是用來簡化新Spring應用的初始搭建以及開發(fā)過程,今天我們就使用純前對按表格控件帶大家了解,如何在Spring Boot框架下實現(xiàn)Excel服務端導入導出,需要的朋友可以參考下2023-06-06
JUnit測試控制@Test執(zhí)行順序的三種方式小結(jié)
這篇文章主要介紹了JUnit測試控制@Test執(zhí)行順序的三種方式小結(jié),具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2021-09-09
java利用Tabula實現(xiàn)對PDF內(nèi)表格數(shù)據(jù)提取
Tabula是一個開源工具,用于從PDF文檔中提取表格數(shù)據(jù),下面小編就來和大家詳細介紹一下java如何通過Tabula對PDF文件內(nèi)表格進行數(shù)據(jù)提取吧2023-09-09

