-
Notifications
You must be signed in to change notification settings - Fork 918
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #90 from RegimenArsenic/master
初步增加web-http聊天功能
- Loading branch information
Showing
10 changed files
with
794 additions
and
1 deletion.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,107 @@ | ||
# encoding:utf-8 | ||
|
||
import jwt | ||
import datetime | ||
import time | ||
from flask import jsonify, request | ||
from common import const | ||
from config import channel_conf | ||
|
||
|
||
class Auth(): | ||
def __init__(self, login): | ||
# argument 'privilegeRequired' is to set up your method's privilege | ||
# name | ||
self.login = login | ||
super(Auth, self).__init__() | ||
|
||
@staticmethod | ||
def encode_auth_token(user_id, login_time): | ||
""" | ||
生成认证Token | ||
:param user_id: int | ||
:param login_time: datetime | ||
:return: string | ||
""" | ||
try: | ||
payload = { | ||
'iss': 'ken', # 签名 | ||
'exp': datetime.datetime.utcnow() + datetime.timedelta(days=0, hours=10), # 过期时间 | ||
'iat': datetime.datetime.utcnow(), # 开始时间 | ||
'data': { | ||
'id': user_id, | ||
'login_time': login_time | ||
} | ||
} | ||
return jwt.encode( | ||
payload, | ||
channel_conf(const.HTTP).get('http_auth_secret_key'), | ||
algorithm='HS256' | ||
) # 加密生成字符串 | ||
except Exception as e: | ||
return e | ||
|
||
@staticmethod | ||
def decode_auth_token(auth_token): | ||
""" | ||
验证Token | ||
:param auth_token: | ||
:return: integer|string | ||
""" | ||
try: | ||
# 取消过期时间验证 | ||
payload = jwt.decode(auth_token, channel_conf(const.HTTP).get( | ||
'http_auth_secret_key'), algorithms='HS256') # options={'verify_exp': False} 加上后不验证token过期时间 | ||
if ('data' in payload and 'id' in payload['data']): | ||
return payload | ||
else: | ||
raise jwt.InvalidTokenError | ||
except jwt.ExpiredSignatureError: | ||
return 'Token过期' | ||
except jwt.InvalidTokenError: | ||
return '无效Token' | ||
|
||
|
||
def authenticate(password): | ||
""" | ||
用户登录,登录成功返回token | ||
:param password: | ||
:return: json | ||
""" | ||
authPassword = channel_conf(const.HTTP).get('http_auth_password') | ||
if (authPassword != password): | ||
return False | ||
else: | ||
login_time = time.strftime("%Y-%m-%d %H:%M:%S", time.localtime()) | ||
token = Auth.encode_auth_token(password, login_time) | ||
return token | ||
|
||
|
||
def identify(request): | ||
""" | ||
用户鉴权 | ||
:return: list | ||
""" | ||
try: | ||
if (request is None): | ||
return False | ||
authorization = request.cookies.get('Authorization') | ||
if (authorization): | ||
payload = Auth.decode_auth_token(authorization) | ||
if not isinstance(payload, str): | ||
authPassword = channel_conf( | ||
const.HTTP).get('http_auth_password') | ||
password = payload['data']['id'] | ||
if (password != authPassword): | ||
return False | ||
else: | ||
return True | ||
return False | ||
|
||
except jwt.ExpiredSignatureError: | ||
#result = 'Token已更改,请重新登录获取' | ||
return False | ||
|
||
except jwt.InvalidTokenError: | ||
#result = '没有提供认证token' | ||
return False |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,66 @@ | ||
# encoding:utf-8 | ||
|
||
import json | ||
from channel.http import auth | ||
from flask import Flask, request, render_template, make_response | ||
from datetime import timedelta | ||
from common import const | ||
from config import channel_conf | ||
from channel.channel import Channel | ||
http_app = Flask(__name__,) | ||
# 自动重载模板文件 | ||
http_app.jinja_env.auto_reload = True | ||
http_app.config['TEMPLATES_AUTO_RELOAD'] = True | ||
|
||
# 设置静态文件缓存过期时间 | ||
http_app.config['SEND_FILE_MAX_AGE_DEFAULT'] = timedelta(seconds=1) | ||
|
||
|
||
@http_app.route("/chat", methods=['POST']) | ||
def chat(): | ||
if (auth.identify(request) == False): | ||
return | ||
data = json.loads(request.data) | ||
if data: | ||
msg = data['msg'] | ||
if not msg: | ||
return | ||
reply_text = HttpChannel().handle(data=data) | ||
return {'result': reply_text} | ||
|
||
|
||
@http_app.route("/", methods=['GET']) | ||
def index(): | ||
if (auth.identify(request) == False): | ||
return login() | ||
return render_template('index.html') | ||
|
||
|
||
@http_app.route("/login", methods=['POST', 'GET']) | ||
def login(): | ||
response = make_response("<html></html>",301) | ||
response.headers.add_header('content-type','text/plain') | ||
response.headers.add_header('location','./') | ||
if (auth.identify(request) == True): | ||
return response | ||
else: | ||
if request.method == "POST": | ||
token = auth.authenticate(request.form['password']) | ||
if (token != False): | ||
response.set_cookie(key='Authorization', value=token) | ||
return response | ||
else: | ||
return render_template('login.html') | ||
response.headers.set('location','./login?err=登录失败') | ||
return response | ||
|
||
class HttpChannel(Channel): | ||
def startup(self): | ||
http_app.run(host='0.0.0.0', port=channel_conf(const.HTTP).get('port')) | ||
|
||
def handle(self, data): | ||
context = dict() | ||
id = data["id"] | ||
context['from_user_id'] = str(id) | ||
return super().build_reply_content(data["msg"], context) | ||
|
Oops, something went wrong.