perf: 优化登录页面

pull/8457/head
ibuler 2022-06-21 16:18:13 +08:00
parent 7c1882bb53
commit f1a22575d3
9 changed files with 180 additions and 56 deletions

View File

@ -38,6 +38,8 @@
background-color: #ffffff;
height: 1px;
margin: 20px 0;
width: 30%;
display: inline-block;
}
.login-content {
@ -78,7 +80,7 @@
margin-bottom: 0;
}
.captch-field .has-error .help-block {
.captcha-field .has-error .help-block {
margin-top: -8px !important;
}
@ -87,25 +89,32 @@
}
.jms-title {
padding: 60px 10px 10px 60px;
padding: 60px 10px 10px;
}
.no-captcha-challenge .jms-title {
padding: 60px 10px 10px 60px;
padding: 60px 10px 10px;
}
.no-captcha-challenge .welcome-message {
padding-top: 10px;
}
.more-login-items {
margin-top: 10px;
}
.more-login-item {
border-right: 1px dashed #dedede;
padding-left: 5px;
padding-right: 5px;
padding: 2px 5px;
}
.more-login-item:last-child {
border: none;
border-right: none;
}
.more-login-item:hover {
color: #334554;
}
.select-con {
@ -117,6 +126,7 @@
}
.login-page-language {
font-size: 12px!important;
margin-right: -11px !important;
padding-top: 12px !important;
padding-left: 0 !important;
@ -136,7 +146,32 @@
font-weight:400;
color: #151515;
letter-spacing: 0;
text-align: left;
}
.more-methods-title {
position: relative;
}
.more-methods-title:before, .more-methods-title:after {
position: absolute;
top: 50%;
transform: translateY(-50%);
content: '';
border: 1px dashed #e7eaec;
width: 35%;
}
.more-methods-title:before {
left: 0;
}
.more-methods-title:after {
right: 0;
}
.more-methods-title.ja:before, .more-methods-title.ja:after{
width: 26%;
}
.captcha-field .form-group {
margin-bottom: 5px;
}
.auto-login.form-group .checkbox {
margin: 5px 0;
}
</style>
</head>
@ -168,7 +203,7 @@
</li>
</ul>
<div class="jms-title">
<span style="">{% trans 'Login' %}</span>
<span style="">{{ JMS_TITLE }}</span>
</div>
<div class="contact-form col-md-10 col-md-offset-1">
<form id="login-form" action="" method="post" role="form" novalidate="novalidate">
@ -202,18 +237,18 @@
{% include '_mfa_login_field.html' %}
</div>
{% elif form.captcha %}
<div class="captch-field">
<div class="captcha-field">
{% bootstrap_field form.captcha show_label=False %}
</div>
{% endif %}
<div class="form-group" style="padding-top: 5px; margin-bottom: 10px">
<div class="form-group auto-login" style="padding-top: 5px; margin-bottom: 0">
<div class="row">
<div class="col-md-6" style="text-align: left">
{% if form.auto_login %}
{% bootstrap_field form.auto_login form_group_class='' %}
{% endif %}
</div>
<div class="col-md-6">
<div class="col-md-6" style="line-height: 25px">
<a id="forgot_password" href="{{ forgot_password_url }}" style="float: right">
<small>{% trans 'Forgot password' %}?</small>
</a>
@ -221,15 +256,18 @@
</div>
</div>
<div class="form-group" style="">
<button type="submit" class="btn btn-transparent" onclick="doLogin();return false;">{% trans 'Login' %}</button>
<div class="form-group" style="margin-bottom: 10px;margin-top: 5px">
<button type="submit" class="btn btn-transparent" onclick="doLogin();return false;">
{% trans 'Login' %}
</button>
</div>
<div>
{% if auth_methods %}
<div class="hr-line-dashed"></div>
<div style="display: inline-block; float: left">
<b class="text-muted text-left" >{% trans "More login options" %}</b>
<div class="more-methods-title {{ current_lang.code }}">
{% trans "More login options" %}
</div>
<div class="more-login-items">
{% for method in auth_methods %}
<a href="{{ method.url }}" class="more-login-item">
<i class="fa"><img src="{{ method.logo }}" height="13" width="13"></i> {{ method.name }}

View File

@ -1,5 +1,6 @@
from channels.auth import AuthMiddlewareStack
from channels.routing import ProtocolTypeRouter, URLRouter
from django.core.asgi import get_asgi_application
from ops.urls.ws_urls import urlpatterns as ops_urlpatterns
from notifications.urls.ws_urls import urlpatterns as notifications_urlpatterns
@ -12,4 +13,5 @@ application = ProtocolTypeRouter({
'websocket': AuthMiddlewareStack(
URLRouter(urlpatterns)
),
"http": get_asgi_application(),
})

View File

@ -11,10 +11,19 @@ from django.urls import reverse_lazy
from .. import const
from ..const import CONFIG
def exist_or_default(path, default):
if not os.path.exists(path):
path = default
return path
# Build paths inside the project like this: os.path.join(BASE_DIR, ...)
VERSION = const.VERSION
BASE_DIR = const.BASE_DIR
PROJECT_DIR = const.PROJECT_DIR
DATA_DIR = os.path.join(PROJECT_DIR, 'data')
CERTS_DIR = os.path.join(DATA_DIR, 'certs')
# Quick-start development settings - unsuitable for production
# See https://docs.djangoproject.com/en/1.10/howto/deployment/checklist/
@ -149,7 +158,6 @@ SESSION_EXPIRE_AT_BROWSER_CLOSE = True
SESSION_EXPIRE_AT_BROWSER_CLOSE_FORCE = CONFIG.SESSION_EXPIRE_AT_BROWSER_CLOSE_FORCE
SESSION_SAVE_EVERY_REQUEST = CONFIG.SESSION_SAVE_EVERY_REQUEST
SESSION_ENGINE = "django.contrib.sessions.backends.cache"
SESSION_CACHE_ALIAS = "default"
MESSAGE_STORAGE = 'django.contrib.messages.storage.cookie.CookieStorage'
# Database
@ -169,7 +177,6 @@ DATABASES = {
}
}
DB_CA_PATH = os.path.join(PROJECT_DIR, 'data', 'certs', 'db_ca.pem')
if CONFIG.DB_ENGINE.lower() == 'mysql':
DB_OPTIONS['init_command'] = "SET sql_mode='STRICT_TRANS_TABLES'"
@ -253,44 +260,40 @@ FILE_UPLOAD_PERMISSIONS = 0o644
FILE_UPLOAD_DIRECTORY_PERMISSIONS = 0o755
# Cache use redis
REDIS_SSL_KEYFILE = os.path.join(PROJECT_DIR, 'data', 'certs', 'redis_client.key')
if not os.path.exists(REDIS_SSL_KEYFILE):
REDIS_SSL_KEYFILE = None
REDIS_SSL_CERTFILE = os.path.join(PROJECT_DIR, 'data', 'certs', 'redis_client.crt')
if not os.path.exists(REDIS_SSL_CERTFILE):
REDIS_SSL_CERTFILE = None
REDIS_SSL_CA_CERTS = os.path.join(PROJECT_DIR, 'data', 'certs', 'redis_ca.crt')
if not os.path.exists(REDIS_SSL_CA_CERTS):
REDIS_SSL_CA_CERTS = os.path.join(PROJECT_DIR, 'data', 'certs', 'redis_ca.pem')
if not os.path.exists(REDIS_SSL_CA_CERTS):
REDIS_SSL_CA_CERTS = None
REDIS_SSL_KEYFILE = exist_or_default(os.path.join(CERTS_DIR, 'redis_client.key'), None)
REDIS_SSL_CERTFILE = exist_or_default(os.path.join(CERTS_DIR, 'redis_client.crt'), None)
REDIS_SSL_CA_CERTS = exist_or_default(os.path.join(CERTS_DIR, 'redis_ca.pem'), None)
REDIS_SSL_CA_CERTS = exist_or_default(os.path.join(CERTS_DIR, 'redis_ca.crt'), REDIS_SSL_CA_CERTS)
REDIS_SSL_REQUIRED = CONFIG.REDIS_SSL_REQUIRED or 'none'
REDIS_LOCATION_NO_DB = '%(protocol)s://:%(password)s@%(host)s:%(port)s/{}' % {
'protocol': 'rediss' if CONFIG.REDIS_USE_SSL else 'redis',
'password': CONFIG.REDIS_PASSWORD,
'host': CONFIG.REDIS_HOST,
'port': CONFIG.REDIS_PORT,
}
CACHES = {
'default': {
'BACKEND': 'redis_lock.django_cache.RedisCache',
'LOCATION': '%(protocol)s://:%(password)s@%(host)s:%(port)s/%(db)s' % {
'protocol': 'rediss' if CONFIG.REDIS_USE_SSL else 'redis',
'password': CONFIG.REDIS_PASSWORD,
'host': CONFIG.REDIS_HOST,
'port': CONFIG.REDIS_PORT,
'db': CONFIG.REDIS_DB_CACHE,
},
'OPTIONS': {
"REDIS_CLIENT_KWARGS": {"health_check_interval": 30},
"CONNECTION_POOL_KWARGS": {
'ssl_cert_reqs': REDIS_SSL_REQUIRED,
"ssl_keyfile": REDIS_SSL_KEYFILE,
"ssl_certfile": REDIS_SSL_CERTFILE,
"ssl_ca_certs": REDIS_SSL_CA_CERTS
} if CONFIG.REDIS_USE_SSL else {}
}
REDIS_CACHE_DEFAULT = {
'BACKEND': 'redis_lock.django_cache.RedisCache',
'LOCATION': REDIS_LOCATION_NO_DB.format(CONFIG.REDIS_DB_CACHE),
'OPTIONS': {
"REDIS_CLIENT_KWARGS": {"health_check_interval": 30},
"CONNECTION_POOL_KWARGS": {
'ssl_cert_reqs': REDIS_SSL_REQUIRED,
"ssl_keyfile": REDIS_SSL_KEYFILE,
"ssl_certfile": REDIS_SSL_CERTFILE,
"ssl_ca_certs": REDIS_SSL_CA_CERTS
} if CONFIG.REDIS_USE_SSL else {}
}
}
REDIS_CACHE_SESSION = dict(REDIS_CACHE_DEFAULT)
REDIS_CACHE_SESSION['LOCATION'] = REDIS_LOCATION_NO_DB.format(CONFIG.REDIS_DB_SESSION)
CACHES = {
'default': REDIS_CACHE_DEFAULT,
'session': REDIS_CACHE_SESSION
}
SESSION_CACHE_ALIAS = "session"
FORCE_SCRIPT_NAME = CONFIG.FORCE_SCRIPT_NAME
SESSION_COOKIE_SECURE = CONFIG.SESSION_COOKIE_SECURE

View File

@ -64,7 +64,7 @@ SWAGGER_SETTINGS = {
# Captcha settings, more see https://django-simple-captcha.readthedocs.io/en/latest/advanced.html
CAPTCHA_IMAGE_SIZE = (140, 34)
CAPTCHA_IMAGE_SIZE = (180, 34)
CAPTCHA_FOREGROUND_COLOR = '#001100'
CAPTCHA_NOISE_FUNCTIONS = ('captcha.helpers.noise_dots',)
CAPTCHA_CHALLENGE_FUNCT = 'captcha.helpers.math_challenge'
@ -130,6 +130,7 @@ CELERY_TASK_EAGER_PROPAGATES = True
CELERY_WORKER_REDIRECT_STDOUTS = True
CELERY_WORKER_REDIRECT_STDOUTS_LEVEL = "INFO"
CELERY_TASK_SOFT_TIME_LIMIT = 3600
if CONFIG.REDIS_USE_SSL:
CELERY_BROKER_USE_SSL = CELERY_REDIS_BACKEND_USE_SSL = {
'ssl_cert_reqs': REDIS_SSL_REQUIRED,

View File

@ -5,5 +5,5 @@ from .. import ws
app_name = 'notifications'
urlpatterns = [
path('ws/notifications/site-msg/', ws.SiteMsgWebsocket, name='site-msg-ws'),
]
path('ws/notifications/site-msg/', ws.SiteMsgWebsocket.as_asgi(), name='site-msg-ws'),
]

View File

@ -5,5 +5,5 @@ from .. import ws
app_name = 'ops'
urlpatterns = [
path('ws/ops/tasks/log/', ws.TaskLogWebsocket, name='task-log-ws'),
path('ws/ops/tasks/log/', ws.TaskLogWebsocket.as_asgi(), name='task-log-ws'),
]

29
data/certs/redis_ca.crt Executable file
View File

@ -0,0 +1,29 @@
-----BEGIN CERTIFICATE-----
MIIE5jCCAs4CCQCtb8sSCTlXlzANBgkqhkiG9w0BAQsFADA1MRMwEQYDVQQKDApS
ZWRpcyBUZXN0MR4wHAYDVQQDDBVDZXJ0aWZpY2F0ZSBBdXRob3JpdHkwHhcNMjIw
NjIxMDM0NTIzWhcNMzIwNjE4MDM0NTIzWjA1MRMwEQYDVQQKDApSZWRpcyBUZXN0
MR4wHAYDVQQDDBVDZXJ0aWZpY2F0ZSBBdXRob3JpdHkwggIiMA0GCSqGSIb3DQEB
AQUAA4ICDwAwggIKAoICAQD5mFMSqN9pG1jRrT8vZPyb1umWMMjaOIIwJ5+Rj7b/
AvtBOKX5eragRMLPdlZQ+L5VCyQUu7BS7z7YZ/voDf8in50DVpSjNCpYHPX7olQp
ASPgjGd+hHe8dNTmSeNQArboGpJs9q5ygJRXiS+SHGyvzLsuA3AmO3NO9guumy6o
pc3AkWtBNcHapL8ZJ14/rfqDENXkhaVdjrv0nB1jwenx9y5IGyMUnVLjxfjaZeTT
qNOJwdp5kSr7lnZhy++F5BtWn3J+gGO0jbWUIj1FawqMPn0Oqh1OL/h6Mtvin4y3
UeRJhMK3SwkK7aCJzXWTEyBWnB5rUoBFIoBisdr2NSkG/h/5p66wQ24c+d1pf1Vi
km32+7UZjBzoCadP0MiBSOi39e6hUdGDuB/IV0moJ+w4qQbjO6DcqACmeDlKpcAr
+8w8XV3GIBKDcihlxExBGE0kwQ+Z99pRfSQlA5sYPVggU96y3Cqmw93pV3HPy8H0
fDia35EEvgEJsbB8+lkBUUtvn/MkqfBpTvV/U0ZwlEAEH6K4psgygbSGChj98yEE
WGll/RlfbLvW5rAOWSgdeE0SVcwL6VEjCasKUSqc1SU+3tdfymSwprnaiNsDVnPt
x0A/QhNPSXyz4Hw2NULDbLVwpN9IT7n3EisWhXMEJFgJvrdCQD82SGYK0qgbNk1H
WQIDAQABMA0GCSqGSIb3DQEBCwUAA4ICAQDPHV6Ruha9ubIlfotnBD4wioFQDj7Y
rQO3HJ5lnL7Byd6p6v7oIkACjOrD1qwoiaA7r1RKPyTKJfRLZRXoGW7z+4LB2sSa
tejIT7rnHs0WIFJsvyahUj36qBmdSnTd+gZgctLp9x4gI6OCjgTWKhgQCbmLOHbg
kIfFOISV7bCCd19/qx6f2zQm2Di6rGsNbpRLl9TrkDravriBrogoHttzhVcd0Z8A
j8NiGIWwJGd/UjklK7tsFZgrjHyIgXDrEmq1a8/cM3U0AWEg50YCgpLILwNTBBYo
9mskfbvT+Ml9NVt4Mhtmn4ei1QfRQiJ78+l8rTh2ca/fAKmPAc7wIdwxRoHTYUqU
iYBuCDcRvGW/hXTGtfs+nQUIYzjRPVNHiw8wUCEE4FEcPl7eDe1w+yQfUYRHE33p
N0s/7k7Zo0o7ykXFMvQx3aghIEovWxFvL79ksfRsHmXAg+Y9fL2tmnlJS1jMGks4
oOzJcL08PyJ2YvKVnJtRpfBjAzRSf+uwKzjS5fw5EY03eYZ3jH0FNU8VuR5doEfl
nAe8n8d7tU8OJiWgXdidoyFH2gJ9uQouswyRrSuuuYcakAYZNfxBcYJG6QXKCS4c
zRGCoEBT3CyHr94utkeEpeb1vuWYnURmhK4XD/kj89sFmrt1QAGYBTkyGLf4qrSc
ZUMT2ZjXaobfSA==
-----END CERTIFICATE-----

24
data/certs/redis_client.crt Executable file
View File

@ -0,0 +1,24 @@
-----BEGIN CERTIFICATE-----
MIIEEDCCAfigAwIBAgIUXAg7+ejbaulXINeL9RuhJ9Qa8zkwDQYJKoZIhvcNAQEL
BQAwNTETMBEGA1UECgwKUmVkaXMgVGVzdDEeMBwGA1UEAwwVQ2VydGlmaWNhdGUg
QXV0aG9yaXR5MB4XDTIyMDYyMTAzNDUyM1oXDTIzMDYyMTAzNDUyM1owKzETMBEG
A1UECgwKUmVkaXMgVGVzdDEUMBIGA1UEAwwLQ2xpZW50LW9ubHkwggEiMA0GCSqG
SIb3DQEBAQUAA4IBDwAwggEKAoIBAQDVimXUfrkWzrHicPSKc+qnFJJbZENYkMPn
PmTySdkuv5opc5aE4LTjDVA63QHi61b1Lt1xw4b+JHNRQ9ocqG+bMhefLnfVjsN2
jPI7W7pzeSfhdXHbr32UuUHixpCov2/67MdUlI0LS3ZkeynG2tXHvXmfgUzinz2K
Hs08qmmo3jz8JwTnhb76yC+lw6yvZRM3f/S62fF/bWXQDhJZfLH+3hPiiCaFkTOl
z9P8bPqJzaHVw7odeQEuZF6wkr1quY8DhRpvQ8WmVMTLbJPge2VIt8aGQ/Y5d1X7
bV1k4I1ZNr85R0yNk5r5f1wQS1QeYi4aoQcrNWwp+cUmNBqYv423AgMBAAGjIjAg
MAsGA1UdDwQEAwIFoDARBglghkgBhvhCAQEEBAMCB4AwDQYJKoZIhvcNAQELBQAD
ggIBAIFVuPNIwAuAYmwgV6942YR9n4jgyQENY2mnG2yQLXe3gP12ABZtlIhK1VQM
+trGnFQ5g2pcDuLdqN8MuRcu4axJOUOBf3pEVnQlC6yACD4r+b5xe4itJvYvZpuO
70YGoKOyBRZxtulxqCfFIoSOpDCZa14AL8RwOwMGyL6FT9ni9jDE+NNgNy3DMciA
89iOwGe/NhUcrs07i1S/sb9dsfmd7PH+3EC2FtEEa5/ls8dp/S911XXfFsYNAy5B
D/qZo2nSiLB/8RJk9wJNG6DHB1KG8tmPxYOlji+H3wESFkW6Laa7Sd4sk4ebi7sr
jPUVvfhDETRn63+qP8x56xUIWi2DADKg73TFeKyT0uOZMWtcBFKckE4KGkM5KkCI
2lrCE+HeoA0Tu0nq41PxvarAMc2/Js8xa8DJstECVZe4nBQMbNRrYPb0uSywm7aq
jyC5Rn71BIpE+nRIXNM9jum/bQR6W37epUzmqrQhjILb6S4AzZKzMHxdhUfpDnVJ
mw3ky9kMabYfL3PMPdE9aNPau56Tds2sT9M8p8sT/g/nayrhFujzyGgByqgCD0tD
2i5ukT7B2I4yDNiaeEQrEKcoQD+QH32aNlk7ch4D6Ghv8ABCToV/IViqvERd5HZL
LfISko9/FJ/aOzd/6CryTnElpQzA8PgORwlcEyV9It57AgDd
-----END CERTIFICATE-----

27
data/certs/redis_client.key Executable file
View File

@ -0,0 +1,27 @@
-----BEGIN RSA PRIVATE KEY-----
MIIEowIBAAKCAQEA1Ypl1H65Fs6x4nD0inPqpxSSW2RDWJDD5z5k8knZLr+aKXOW
hOC04w1QOt0B4utW9S7dccOG/iRzUUPaHKhvmzIXny531Y7DdozyO1u6c3kn4XVx
2699lLlB4saQqL9v+uzHVJSNC0t2ZHspxtrVx715n4FM4p89ih7NPKppqN48/CcE
54W++sgvpcOsr2UTN3/0utnxf21l0A4SWXyx/t4T4ogmhZEzpc/T/Gz6ic2h1cO6
HXkBLmResJK9armPA4Uab0PFplTEy2yT4HtlSLfGhkP2OXdV+21dZOCNWTa/OUdM
jZOa+X9cEEtUHmIuGqEHKzVsKfnFJjQamL+NtwIDAQABAoIBAEBUPA8CygF77Qy5
WIHpH7SLtvd/QeaJXero2gI/iwTRRcDdCGgpRXTtCtFgyPOyT/T21FE0RROEqZS+
qxNdDpojQgh7ODCGnI23MjX9kTK+OexqtA0pVdya3qVRijy7xyFBeV8ajU7swdLN
Y617OVG928jYa/ANZr2YP93ZvJDZLP1+If9lAZktMdZk2yxnTnT9mYHOwtuLzHG4
kYMlJ285QZw2vINl2hPCTfNfVMCqLowqa9C0fztT5OiZp++eBKbB8NbsU1k4EDyn
WSVsOTkT1mSXrJsLmAy4NGIWWqq8i+yEl6cY5/g/pAn/7BTHVh5rf+MKoYDI58yA
xZIQZSECgYEA/0rQkY/Z+dVkp7vsm0DrXG/W9DmgpJX/5BFQCvSdC7bBzCYqpw+4
cL0soppuGDzdKOWUulFZHoysYa08jcHbSolXycCoPFTklmSlMT1X8CmY6T3IZow7
OqCOSfUmWAgsFzzRLESmvi2tZKsvfhThuYYxl/8NTxq1VGOalfm2+9ECgYEA1iHz
gkXuvieYhnq+/qO5H2C3qSgF4RCAKnkV3+1nTH7zSCuqjJFewJRtYpu4KZP/TbCl
xhF97tk6KDzCLZ7OhcRglyT6Sv5UbUEdvt8uoFkvLupYGE9DWp1zohdm8+lo3PQ4
jvIvLEQ/CbINnFOZwS1DzDAhd7DgxX3h1Po9uwcCgYBAo97fnH7ixWdxGSI1xWBS
zXat7BGC2wAp7UBJJdrF5oZ3fIp8NnzK/vtYSKXruS1+d3MLIiHgnFnheY3FjvpJ
izERQpjWfeBLPDyflRq5Eq9HD3+4h3VPyOt+SnZk/9y6HYoRHWji6onm3XlvATaO
VS4lgE0MZITZU0cHBm2QoQKBgQCUvji8gX95r1+P6qvJjkkFttVdN2P+FswwtLOx
POPIi1bLByoNQt2iwHfLS4f9ucRaXx6IG5Zy14pCcRIhRnMHEIZX92O1vD1BNz5G
XBmzYMAZwsc2+7g5ta2hJshpHfWtpiezhB+ojC+NuJUjxh7DxYGW0MgusDsydGLu
4nUG+QKBgFSCE9J1pueDawCpg4zAsOgC+13lbDQ+l8koGEgGdjF3xd5OfZvGTtUG
Ea4Z8F3eNN+fus/IksoyKk1EISAhHVzj3bRKoavfTb716kFeRQ0xePQ0dabpFBxp
xdKCUo37KFQDNknPZXX3AamdkiQdy5/C7hkpWjMtHYYV6CAK1Z16
-----END RSA PRIVATE KEY-----