1、安装组件
npm install koa koa-bodyparser koa-router koa-static koa-views jsonwebtoken
项目结构
project/
├── public/
│ ├── index.html
│ └── dashboard.html
└── App.mjs
2、App.mjs
import Koa from 'koa';
import koaBody from 'koa-bodyparser';
import koaRouter from 'koa-router';
import koaStatic from 'koa-static';
import jwt from 'jsonwebtoken';
import fs from 'fs';
import path from 'path';
const app = new Koa();
const router = new koaRouter();
app.use(koaBody());
app.use(koaStatic('public'));
/*
模拟用户密码数据库
*/
const users = [
{
email: 'user1@example.com',
password: 'password1',
role: 'user',
},
{
email: 'user2@example.com',
password: 'password2',
role: 'user',
},
{
email: 'admin@example.com',
password: 'adminpassword',
role: 'admin',
},
];
function generateToken(user) {
const token = jwt.sign({ email: user.email, role: user.role }, 'secret_key', {
expiresIn: '1h',
});
return token;
}
function authenticate(email, password) {
const user = users.find((user) => user.email === email && user.password === password);
return user;
}
router.post('/api/login', async (ctx) => {
const { email, password } = ctx.request.body;
const user = authenticate(email, password);
if (!user) {
ctx.status = 401;
ctx.body = { message: 'Invalid login credentials' };
return;
}
const token = generateToken(user);
ctx.body = { token };
});
router.post('/api/register', async (ctx) => {
const { email, password } = ctx.request.body;
const user = { email, password, role: 'user' };
users.push(user);
const token = generateToken(user);
ctx.body = { token };
});
function authMiddleware() {
return async (ctx, next) => {
const authHeader = ctx.request.headers.authorization;
if (!authHeader) {
ctx.status = 401;
ctx.body = { message: 'Authorization header missing' };
return;
}
const [bearer, token] = authHeader.split(' ');
if (bearer !== 'Bearer' || !token) {
ctx.status = 401;
ctx.body = { message: 'Invalid Authorization header' };
return;
}
try {
const decoded = jwt.verify(token, 'secret_key');
ctx.state.user = decoded;
await next();
} catch (err) {
ctx.status = 401;
ctx.body = { message: 'Invalid or expired token' };
}
};
}
router.get('/api/user', authMiddleware(), async (ctx) => {
ctx.body = ctx.state.user;
});
router.get('/', async (ctx) => {
ctx.redirect('/index.html');
});
app.use(router.routes());
app.use(router.allowedMethods());
const port = process.env.PORT || 3000;
app.listen(port, () => {
console.log(`Server running on port ${port}`);
});
index.html
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8" />
<title>Example App</title>
</head>
<body>
<h1>Welcome to Example App</h1>
<div>
<h2>Login</h2>
<form id="login-form">
<div>
<label for="email">Email:</label>
<input type="email" name="email" id="email" />
</div>
<div>
<label for="password">Password:</label>
<input type="password" name="password" id="password" />
</div>
<div>
<button type="submit">Login</button>
</div>
</form>
</div>
<div>
<h2>Register</h2>
<form id="register-form">
<div>
<label for="email">Email:</label>
<input type="email" name="email" id="register-email" />
</div>
<div>
<label for="password">Password:</label>
<input type="password" name="password" id="register-password" />
</div>
<div>
<button type="submit">Register</button>
</div>
</form>
</div>
<script src="https://code.jquery.com/jquery-3.6.0.min.js"></script>
<script>
$(document).ready(() => {
$('#login-form').submit((event) => {
event.preventDefault();
const email = $('#email').val();
const password = $('#password').val();
$.post('/api/login', { email, password })
.done((response) => {
localStorage.setItem('token', response.token);
window.location.href = '/dashboard.html';
})
.fail((xhr, status, error) => {
alert(xhr.responseJSON.message);
});
});
$('#register-form').submit((event) => {
event.preventDefault();
const email = $('#register-email').val();
const password = $('#register-password').val();
$.post('/api/register', { email, password })
.done((response) => {
localStorage.setItem('token', response.token);
window.location.href = '/dashboard.html';
})
.fail((xhr, status, error) => {
alert(xhr.responseJSON.message);
});
});
});
</script>
</body>
</html>
dashboard.html
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8" />
<title>Dashboard</title>
</head>
<body>
<h1>Welcome to the Dashboard</h1>
<p>You are logged in!</p>
<script src="https://code.jquery.com/jquery-3.6.0.min.js"></script>
<script>
$(document).ready(() => {
const token = localStorage.getItem('token');
if (!token) {
window.location.href = '/index.html';
} else {
$.ajax({
url: '/api/user',
method: 'GET',
headers: { Authorization: `Bearer ${token}` },
})
.done((response) => {
$('h1').append(`, ${response.email}!`);
})
.fail((xhr, status, error) => {
alert(xhr.responseJSON.message);
window.location.href = '/index.html';
});
}
});
</script>
</body>
</html>
node.exe App.mjs 启动服务
在浏览器中访问 http://localhost:3000/ 查看应用程序。
该文章演示了一个使用Koa.js框架构建的应用,包括处理登录和注册功能,采用JSONWebTokens(JWT)进行用户身份验证,并通过中间件实现授权。用户数据存储在内存中,登录成功后生成并返回JWT,客户端保存用于后续请求的授权。
828

被折叠的 条评论
为什么被折叠?



