提交 aa439354c770272bc256b47ccf25cd27b9fddd27

作者 qianyingz
1 个父辈 0b01fbc0

swagger支持authentication

1 import decimal 1 import decimal
  2 +from re import template
2 3
3 from flask import Flask as _Flask 4 from flask import Flask as _Flask
4 from flask.json import JSONEncoder as _JSONEncoder 5 from flask.json import JSONEncoder as _JSONEncoder
@@ -58,18 +59,51 @@ def create_app(): @@ -58,18 +59,51 @@ def create_app():
58 app.config['OAUTH2_JWT_KEY'] = 'secret-key' 59 app.config['OAUTH2_JWT_KEY'] = 'secret-key'
59 app.config['OAUTH2_JWT_ALG'] = 'HS256' 60 app.config['OAUTH2_JWT_ALG'] = 'HS256'
60 # app.config['SQLALCHEMY_ECHO'] = True 61 # app.config['SQLALCHEMY_ECHO'] = True
61 - 62 +
62 # allows cookies and credentials to be submitted across domains 63 # allows cookies and credentials to be submitted across domains
63 app.config['CORS_SUPPORTS_CREDENTIALS'] = true 64 app.config['CORS_SUPPORTS_CREDENTIALS'] = true
64 - app.config['CORS_ORIGINS ']="*" 65 + app.config['CORS_ORIGINS '] = "*"
65 66
66 # 跨域设置 67 # 跨域设置
67 CORS(app) 68 CORS(app)
68 69
69 # swagger设置 70 # swagger设置
70 swagger_config = Swagger.DEFAULT_CONFIG 71 swagger_config = Swagger.DEFAULT_CONFIG
  72 + SWAGGER_TEMPLATE = {
  73 + # "openapi": "3.0.0",
  74 + # "components": {
  75 + # "securitySchemes": {
  76 + # "bearerAuth": {
  77 + # "type": "http",
  78 + # "scheme": "bearer",
  79 + # "bearerFormat": "JWT"
  80 + # },
  81 + # }
  82 + # },
  83 + "securityDefinitions": {
  84 + "APIKeyHeader": {
  85 + "type": "apiKey",
  86 + "in": "header",
  87 + "name": "Authorization"
  88 + }
  89 + },
  90 +
  91 + "security": [{
  92 + "APIKeyHeader": []
  93 + }
  94 + ]
  95 + }
  96 +
  97 + swagger_config = Swagger.DEFAULT_CONFIG
71 swagger_config.update(configure.swagger_configure) 98 swagger_config.update(configure.swagger_configure)
72 - Swagger(app, config=swagger_config) 99 + # swagger_config['openapi'] = "3.0.0"
  100 + # swagger_config['swagger_ui_bundle_js'] = '//unpkg.com/swagger-ui-dist@3/swagger-ui-bundle.js'
  101 + # swagger_config['swagger_ui_standalone_preset_js'] = '//unpkg.com/swagger-ui-dist@3/swagger-ui-standalone-preset.js'
  102 + # swagger_config['jquery_js'] = '//unpkg.com/jquery@2.2.4/dist/jquery.min.js'
  103 + # swagger_config['swagger_ui_css'] = '//unpkg.com/swagger-ui-dist@3/swagger-ui.css'
  104 +
  105 + Swagger(app, config=swagger_config,
  106 + template=SWAGGER_TEMPLATE)
73 107
74 # 创建数据库 108 # 创建数据库
75 db.init_app(app) 109 db.init_app(app)
@@ -77,9 +111,12 @@ def create_app(): @@ -77,9 +111,12 @@ def create_app():
77 111
78 # 日志 112 # 日志
79 logging.basicConfig(level=configure.log_level) 113 logging.basicConfig(level=configure.log_level)
80 - log_file = os.path.join(os.path.dirname(os.path.dirname(os.path.realpath(__file__))), "logs", "log.txt")  
81 - handler = logging.FileHandler(log_file, encoding='UTF-8') # 设置日志字符集和存储路径名字  
82 - logging_format = logging.Formatter('[%(levelname)s] %(asctime)s %(message)s') 114 + log_file = os.path.join(os.path.dirname(os.path.dirname(
  115 + os.path.realpath(__file__))), "logs", "log.txt")
  116 + handler = logging.FileHandler(
  117 + log_file, encoding='UTF-8') # 设置日志字符集和存储路径名字
  118 + logging_format = logging.Formatter(
  119 + '[%(levelname)s] %(asctime)s %(message)s')
83 handler.setFormatter(logging_format) 120 handler.setFormatter(logging_format)
84 app.logger.addHandler(handler) 121 app.logger.addHandler(handler)
85 122
@@ -94,14 +131,13 @@ def create_app(): @@ -94,14 +131,13 @@ def create_app():
94 # 不检测https 131 # 不检测https
95 os.environ['OAUTHLIB_INSECURE_TRANSPORT'] = '1' 132 os.environ['OAUTHLIB_INSECURE_TRANSPORT'] = '1'
96 133
97 -  
98 @app.before_first_request 134 @app.before_first_request
99 def init_data(): 135 def init_data():
100 pass 136 pass
101 -  
102 # start_schedule() 137 # start_schedule()
103 return app 138 return app
104 139
  140 +
105 def create_schedule(): 141 def create_schedule():
106 monitor = Flask(__name__) 142 monitor = Flask(__name__)
107 monitor.config['SQLALCHEMY_DATABASE_URI'] = configure.SQLALCHEMY_DATABASE_URI 143 monitor.config['SQLALCHEMY_DATABASE_URI'] = configure.SQLALCHEMY_DATABASE_URI
@@ -112,13 +148,13 @@ def create_schedule(): @@ -112,13 +148,13 @@ def create_schedule():
112 148
113 # allows cookies and credentials to be submitted across domains 149 # allows cookies and credentials to be submitted across domains
114 monitor.config['CORS_SUPPORTS_CREDENTIALS'] = true 150 monitor.config['CORS_SUPPORTS_CREDENTIALS'] = true
115 - monitor.config['CORS_ORIGINS ']="*"  
116 - 151 + monitor.config['CORS_ORIGINS '] = "*"
  152 +
117 # swagger设置 153 # swagger设置
118 swagger_config = Swagger.DEFAULT_CONFIG 154 swagger_config = Swagger.DEFAULT_CONFIG
119 swagger_config.update(configure.swagger_configure) 155 swagger_config.update(configure.swagger_configure)
120 Swagger(monitor, config=swagger_config) 156 Swagger(monitor, config=swagger_config)
121 - 157 +
122 # 创建数据库 158 # 创建数据库
123 db.init_app(monitor) 159 db.init_app(monitor)
124 db.create_all(app=monitor) 160 db.create_all(app=monitor)
@@ -128,9 +164,12 @@ def create_schedule(): @@ -128,9 +164,12 @@ def create_schedule():
128 164
129 # 日志 165 # 日志
130 logging.basicConfig(level=configure.log_level) 166 logging.basicConfig(level=configure.log_level)
131 - log_file = os.path.join(os.path.dirname(os.path.dirname(os.path.realpath(__file__))), "logs", "monitor_log.txt")  
132 - handler = logging.FileHandler(log_file, encoding='UTF-8') # 设置日志字符集和存储路径名字  
133 - logging_format = logging.Formatter('[%(levelname)s] %(asctime)s %(message)s') 167 + log_file = os.path.join(os.path.dirname(os.path.dirname(
  168 + os.path.realpath(__file__))), "logs", "monitor_log.txt")
  169 + handler = logging.FileHandler(
  170 + log_file, encoding='UTF-8') # 设置日志字符集和存储路径名字
  171 + logging_format = logging.Formatter(
  172 + '[%(levelname)s] %(asctime)s %(message)s')
134 handler.setFormatter(logging_format) 173 handler.setFormatter(logging_format)
135 monitor.logger.addHandler(handler) 174 monitor.logger.addHandler(handler)
136 175
@@ -12,7 +12,7 @@ from authlib.integrations.flask_oauth2 import current_token @@ -12,7 +12,7 @@ from authlib.integrations.flask_oauth2 import current_token
12 from . import user_create, client_create, client_query, user_query, user_update, user_delete 12 from . import user_create, client_create, client_query, user_query, user_update, user_delete
13 import configure 13 import configure
14 from app.decorators.auth_decorator import auth_decorator 14 from app.decorators.auth_decorator import auth_decorator
15 - 15 +import time
16 16
17 def current_user(): 17 def current_user():
18 if "id" in session: 18 if "id" in session:
@@ -46,7 +46,6 @@ class DataManager(BlueprintApi): @@ -46,7 +46,6 @@ class DataManager(BlueprintApi):
46 return jsonify(dict(error.get_body())) 46 return jsonify(dict(error.get_body()))
47 if not user: 47 if not user:
48 return render_template("auth/authorize.html", user=user, grant=grant) 48 return render_template("auth/authorize.html", user=user, grant=grant)
49 - # return render_template("auth/login1.html", user=user, grant=grant)  
50 error = "" 49 error = ""
51 if not user: 50 if not user:
52 if not "username" in request.form or not request.form.get("username"): 51 if not "username" in request.form or not request.form.get("username"):
@@ -166,3 +165,21 @@ class DataManager(BlueprintApi): @@ -166,3 +165,21 @@ class DataManager(BlueprintApi):
166 获取client列表 165 获取client列表
167 """ 166 """
168 return client_query.Api().result 167 return client_query.Api().result
  168 +
  169 + @staticmethod
  170 + @bp.route("/init", methods=["GET"])
  171 + def init():
  172 + username = 'admin'
  173 + password = 'admin'
  174 + if not User.query.filter_by(username=username).one_or_none():
  175 + user = User(username=username, password=password, role='admin',
  176 + phone='', company='', position='', email='',
  177 + create_time=time.strftime(
  178 + "%Y-%m-%d %H:%M:%S", time.localtime()),
  179 + update_time=time.strftime("%Y-%m-%d %H:%M:%S", time.localtime()))
  180 + db.sesion.add(user)
  181 + db.session.commit()
  182 + return "创建默认用户成功"
  183 + else:
  184 + return "默认用户已存在"
  185 +
@@ -120,6 +120,18 @@ class HybridGrant(_OpenIDHybridGrant): @@ -120,6 +120,18 @@ class HybridGrant(_OpenIDHybridGrant):
120 120
121 def generate_user_info(self, user, scope): 121 def generate_user_info(self, user, scope):
122 return generate_user_info(user, scope) 122 return generate_user_info(user, scope)
  123 +
  124 +from authlib.oauth2.rfc6749 import grants
  125 +
  126 +class PasswordGrant(grants.ResourceOwnerPasswordCredentialsGrant):
  127 + def authenticate_user(self, username, password):
  128 + user = User.query.filter_by(username=username).first()
  129 + if user.check_password(password):
  130 + return user
  131 +
  132 + TOKEN_ENDPOINT_AUTH_METHODS = [
  133 + 'client_secret_basic', 'client_secret_post'
  134 + ]
123 135
124 136
125 authorization = AuthorizationServer() 137 authorization = AuthorizationServer()
@@ -142,6 +154,7 @@ def config_oauth(app): @@ -142,6 +154,7 @@ def config_oauth(app):
142 ]) 154 ])
143 authorization.register_grant(ImplicitGrant) 155 authorization.register_grant(ImplicitGrant)
144 authorization.register_grant(HybridGrant) 156 authorization.register_grant(HybridGrant)
  157 + authorization.register_grant(PasswordGrant)
145 158
146 # protect resource 159 # protect resource
147 bearer_cls = create_bearer_token_validator(db.session, OAuth2Token) 160 bearer_cls = create_bearer_token_validator(db.session, OAuth2Token)
@@ -5,7 +5,7 @@ deploy_ip_host = "172.26.40.105:8840" @@ -5,7 +5,7 @@ deploy_ip_host = "172.26.40.105:8840"
5 # 系统数据库 5 # 系统数据库
6 6
7 SQLALCHEMY_DATABASE_URI = "postgresql://postgres:chinadci@172.26.60.100:5432/dmap_manager_test" 7 SQLALCHEMY_DATABASE_URI = "postgresql://postgres:chinadci@172.26.60.100:5432/dmap_manager_test"
8 -# SQLALCHEMY_DATABASE_URI = "postgresql://postgres:postgres@localhost:5433/dmap_dms_test" 8 +# SQLALCHEMY_DATABASE_URI = "postgresql://postgres:postgres@localhost:5433/dmap_dms_test1"
9 9
10 # 指定精华表所在位置(必须为空间库),设置为None则存放在各自的实体库中 10 # 指定精华表所在位置(必须为空间库),设置为None则存放在各自的实体库中
11 #VACUATE_DB_URI = None 11 #VACUATE_DB_URI = None
@@ -18,12 +18,13 @@ wmts_url = "http://172.26.99.160:6060" @@ -18,12 +18,13 @@ wmts_url = "http://172.26.99.160:6060"
18 wms_url = "" 18 wms_url = ""
19 19
20 # 固定配置不需要修改 20 # 固定配置不需要修改
  21 +# "openapi": "3.0.2"
21 swagger_configure = {"title": "DMapManager"} 22 swagger_configure = {"title": "DMapManager"}
22 entry_data_thread = 3 23 entry_data_thread = 3
23 scan_module = ["app.modules"] # API所在的模块 24 scan_module = ["app.modules"] # API所在的模块
24 SECRET_KEY = b'_5#y2L"F4Q8z\n\xec]/' 25 SECRET_KEY = b'_5#y2L"F4Q8z\n\xec]/'
25 # 权限 26 # 权限
26 -PermissionActive = False 27 +PermissionActive = True
27 UserPermission = ['admin'] 28 UserPermission = ['admin']
28 MonitorPermission = ['admin'] 29 MonitorPermission = ['admin']
29 DataPermission = ['admin', 'dataman'] 30 DataPermission = ['admin', 'dataman']
  1 +## https://swagger.io/docs/specification/2-0/what-is-swagger/
  2 +## 1 需求:api需要授权
  3 +Swagger(app, config=swagger_config,template=SWAGGER_TEMPLATE)的template中
  4 +### 确定当前使用swagger的标准
  5 +确定当前使用openapi2版本,需要查阅openapi2的文档
  6 +### 了解简单YAML使用方式
  7 +### 配置
注册登录 后发表评论