一个身份认证页面至少需要一个 form
表单,里面需要包括三个 id 分别为 username
, password
, form-submit
的标签,例子如下
<form id="form" action="#" class="form" onsubmit="return submit()">
<input id="username" class="form-input" placeholder="Username" />
<input id="password" class="form-input" type="password" placeholder="Password" />
<button class="form-submit" id="form-submit">Submit</button>
</form>
这样可以完成一个最简单的身份认证功能,用户点击 Submit 即可完成认证
每次用户提交表单后,浏览器会刷新页面,此时服务端会根据发送的 cookie (由注入的 js 脚本自动完成)来判断用户的认证是否成功,如果成功会直接进入正常的业务页面,否则服务端会返回一个 Set-Cookie: sl_auth_verify_error=true; Path=/; Max-Age=3600
的响应来告诉浏览器此次认证失败,可以根据这个行为来自定义错误显示行为,比如定义下面的函数来负责判断是否认证失败
function isAuthFailed() {
return document.cookie.indexOf("sl_auth_verify_error=true") > -1;
}
然后可以基于此函数来定义给用户的错误提示即可。
如果再给上面的基本表单加上一些样式就可以达到和默认的效果一样
<!DOCTYPE html>
<html lang="zh">
<head>
<meta charset="utf-8" />
<title>SafeLine WAF Auth</title>
<meta name="viewport" content="width=device-width,initial-scale=1" />
<style>
html {
height: 100%;
}
body {
background: #f7f8fa;
font-family: system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI",
Roboto, Oxygen, Ubuntu, Cantarell, "Open Sans", "Helvetica Neue",
sans-serif;
margin: 0;
height: 100%;
}
.container {
display: flex;
align-items: center;
justify-content: center;
flex-direction: column;
height: 100%;
}
.title {
display: flex;
align-items: center;
font-size: 24px;
margin-bottom: 5px;
}
.form {
width: 440px;
height: 318px;
background: rgba(255, 255, 255, 0.8);
box-shadow: 0px 8px 15px 0px rgba(145, 158, 171, 0.08);
border-radius: 8px;
border: 2px solid #ffffff;
display: flex;
justify-content: space-between;
flex-direction: column;
padding: 32px;
box-sizing: border-box;
font-size: 16px;
}
.form-field {
width: 376px;
height: 42px;
background: #f7f8fa;
border-radius: 4px;
display: flex;
align-items: center;
border: 1px white solid;
}
.form-field-help {
color: #FF4D4F;
}
.form-field svg {
margin: 0 12px;
}
.form-input {
font-size: 16px;
border: 0;
outline: 0;
background: #f7f8fa;
flex-grow: 1;
width: 100px;
border-radius: 4px;
}
.form-input-error {
border: 1px #FF4D4F solid;
}
.form-submit {
width: 376px;
height: 42px;
background: #0fc6c2;
border-radius: 4px;
border: 0;
color: white;
cursor: pointer;
font-size: 16px;
}
.form-error {
color: lightcoral;
display: none;
}
.form-submit:hover {
background: #09c0c0;
}
.footer {
position: absolute;
bottom: 32px;
left: 0;
width: 100%;
color: #a8a8a8;
font-size: 14px;
text-align: center;
}
.footer-waflink {
color: #0fc6c2;
text-decoration: none;
}
</style>
</head>
<body>
<div class="container">
<form id="form" action="#" class="form" onsubmit="return submit()">
<div class="title">
<img style="margin-right: 15px; height: 32px; width: 30px;"
src="data:image/png;base64,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" />
<span id="title">Authenticate</span>
</div>
<div class="form-error" id="form-error">
Invalid username or password
</div>
<div class="form-field" id="form-field-username">
<svg fill="rgba(0,0,0,0.7)" t="1705641856405" class="icon" viewBox="0 0 1024 1024" version="1.1"
xmlns="http://www.w3.org/2000/svg" p-id="2238" width="16" height="16">
<path
d="M405.230669 310.341694a44.509778 44.509778 0 0 0-44.441511 44.441511v46.62604a44.509778 44.509778 0 0 0 88.951289 0v-46.62604a44.509778 44.509778 0 0 0-44.509778-44.441511z m214.493438 135.577329c24.575951 0 44.509778-19.933827 44.509777-44.509778v-46.62604a44.509778 44.509778 0 0 0-88.951288 0v46.62604c0 24.575951 19.933827 44.509778 44.441511 44.509778z"
p-id="2239"></path>
<path
d="M841.38553 894.088793a213.26464 213.26464 0 0 0-60.415879-116.6675 185.958028 185.958028 0 0 0-38.229257-29.218075c20.889558-14.335971 40.550319-30.719939 58.914015-48.947102A406.936786 406.936786 0 0 0 921.598703 409.601229c0-109.499514-42.598315-212.308909-119.944294-289.654888A406.936786 406.936786 0 0 0 511.999522 0.002048C402.500008 0.002048 299.690613 42.600363 222.344635 119.946341A406.936786 406.936786 0 0 0 102.400341 409.601229c0 109.499514 42.598315 212.308909 119.944294 289.654887 18.227164 18.227164 38.024457 34.611131 58.982282 48.947102-13.38024 7.850651-25.941281 17.612765-37.341792 29.081542a218.794229 218.794229 0 0 0-58.367883 118.510696l-8.191984 70.860659a44.509778 44.509778 0 0 0 88.405156 10.376512l7.987184-69.768394c11.332244-64.375338 56.66122-93.661679 94.139546-93.661679h2.321062l54.067091-2.867194 2.321062-0.136533a412.807708 412.807708 0 0 0 170.666326 0l2.730661 0.273066 53.52096 2.867194h2.321062c49.493234 0 87.790758 46.079908 96.801939 91.272351l6.826653 71.133724c2.047996 22.937554 21.43569 40.277253 44.168445 40.277253l4.300792-0.068266a44.373245 44.373245 0 0 0 40.004186-48.469237l-6.621853-73.796119z m-402.840794-169.437528a40.277253 40.277253 0 0 0-11.059178-2.730661 321.330557 321.330557 0 0 1-144.042379-83.626499 321.46709 321.46709 0 0 1-94.82221-228.829409c0-86.493694 33.723666-167.730865 94.890477-228.829409a321.46709 321.46709 0 0 1 228.761142-94.890477c86.493694 0 167.730865 33.791932 228.829409 94.890477a321.46709 321.46709 0 0 1 94.890477 228.829409 320.989225 320.989225 0 0 1-95.02701 228.692876 321.398824 321.398824 0 0 1-144.588511 83.763032 38.638856 38.638856 0 0 0-8.874649 2.321062 328.771609 328.771609 0 0 1-148.957568 0.409599z"
p-id="2240"></path>
</svg>
<input id="username" class="form-input" placeholder="Username" />
</div>
<div class="form-field-help" id="form-username-help"></div>
<div class="form-field" id="form-field-password">
<svg fill="rgba(0,0,0,0.7)" t="1705642150496" class="icon" viewBox="0 0 1024 1024" version="1.1"
xmlns="http://www.w3.org/2000/svg" p-id="2388" width="16" height="16">
<path
d="M215.771429 983.771429A142.628571 142.628571 0 0 1 73.142857 840.996571V541.403429a142.628571 142.628571 0 0 1 142.628572-142.628572h27.355428v-130.194286A268.873143 268.873143 0 0 1 511.707429 0a268.873143 268.873143 0 0 1 268.580571 268.580571v130.194286h27.867429A142.628571 142.628571 0 0 1 950.857143 541.549714V841.142857a142.628571 142.628571 0 0 1-142.628572 142.628572h-592.457142zM168.228571 541.330286V841.142857a47.542857 47.542857 0 0 0 47.542858 47.542857h592.384a47.542857 47.542857 0 0 0 47.542857-47.542857V541.403429a47.542857 47.542857 0 0 0-47.542857-47.542858H215.771429a47.542857 47.542857 0 0 0-47.542858 47.616z m516.900572-142.628572v-130.194285A173.714286 173.714286 0 0 0 511.780571 95.085714a173.714286 173.714286 0 0 0-173.568 173.494857v130.194286h346.916572zM464.457143 616.082286a47.542857 47.542857 0 1 1 95.085714 0v132.681143a47.542857 47.542857 0 1 1-95.085714 0V616.082286z"
p-id="2389"></path>
</svg>
<input id="password" class="form-input" type="password" placeholder="Password" />
</div>
<div class="form-field-help" id="form-password-help"></div>
<button class="form-submit" id="form-submit">Submit</button>
</form>
</div>
<div class="footer">
<span id="powered-by">Powered by</span>
<a class="footer-waflink" href="https://waf-ce.chaitin.cn">
<span id="waf-title">SafeLine WAF</span>
</a>
<span id="powered-by-tail"></span>
</div>
</body>
</html>