要点:
- 不要通过 form 提交表单的默认方式发送请求,转而使用 fetch 或 ajax
- 客户端注意设置 Authorization 字段的值为 'Basic xxx',通过该 Http 字段传递用户名密码
- base64 的方法在客户端要注意兼容性 btoa ,建议使用现成的库如 'js-base64' 等,NodeJS 方面使用全局的 Buffer
- 服务端验证失败后,注意返回 401,但不用返回 'WWW-Authenticate: Basic realm="..."' 避免浏览器出现弹窗
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>AMD</title>
</head>
<body>
<script defer async="true" src="js/require.js" data-main="js/main"></script>
<!-- BasicAuth -->
<div>
<form id="form" action="">
<input type="text" name="username" id="username">
<input type="password" name="password" id="password">
<button id="login">login</button>
</form>
</div>
</body>
</html>
require.config({
baseUrl: 'js/libs',
paths: {
'zepto': 'zepto.min',
},
shim: {
'zepto': 'zepto',
}
});
define(['zepto'], function ($) {
let $form = $('#form')
$form.on('submit', (e) => {
e.preventDefault()
$.ajax({
// ajax 发送验证请求
type: 'POST',
url: '/login',
headers: {
'Content-Type': 'application/x-www-form-urlencoded',
'Authorization': 'Basic ' + btoa($('#username').val() + ':' + $('#password').val()),
// 通过 Authorization 传递 base64 编码后的用户名密码
},
success: function (data) {
console.dir(data) // 回调
}
})
})
});
const Koa = require('koa')
const static = require('koa-static')
const router = require('koa-better-router')().loadMethods()
const koaBody = require('koa-body')
const app = new Koa()
app.use(koaBody())
app.use(router.middleware())
app.use(static('public'))
app.listen(8080)
router.post('/login', (ctx, next) => {
// 省略从数据库中提取用户密码
if (ctx.get('Authorization') === 'Basic ' + Buffer('fdsa:fdsa').toString('base64')) {
// 获取 Authorization 字段 比对 base64 用户名密码
ctx.body = 'secret'
ctx.type = 'text/html'
ctx.status = 200 // 匹配成功
} else {
ctx.status = 401 // 匹配失败
}
next()
})