技术标签: Powered by 金山文档 Nodejs javascript
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: '[email protected]',
password: 'password1',
role: 'user',
},
{
email: '[email protected]',
password: 'password2',
role: 'user',
},
{
email: '[email protected]',
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/ 查看应用程序。
文章浏览阅读298次。前提:导入需要的2个jar文件,jcommon-版本号.jar,jfreechart-版本号.jar。可以去官网下载:http://sourceforge.net/projects/jfreechart/files/注意:下载的Jfreechart版本不要太高,新版本对中文的显示会出问题,我自己后来下的是1.0.10的版本。 实例一:比较简单的application版本的饼图 _jfreechat使用
文章浏览阅读1.3k次。编写一个控制台应用程序,从键盘中输入一个学生的学号,以及语文、数学、计算机的成就。a) 若是三门成绩之和>=280,显示学号及“是一个成绩优秀的学生!”;b) 若不满足该条件只要语文数学成绩均在95分以上,则显示学号及“语数成绩优秀!”;c) 以上条件都不满足,若计算机成绩是100分,则显示学号及“计算机成绩优秀!”;d) 所有条件都不满足,则显示学号及“仍需努力!”。..._从键盘上获取语文,数学,英语成绩并输出要求有良好的提示信息和良好的命名规范
文章浏览阅读1.1k次。SpringBoot+Mybatis-Plus整合Sharding-JDBC4.0.0实现单库分表 _sharding jdbc 5.1.1 + mybatis plus 多数据源
文章浏览阅读593次。摘要:计算机联锁系统保持长期安全可靠运行对于铁路安全稳定运行至关重要,冗余技术是提高系统可靠性的主要手段,因此研究计算机联锁系统冗余技术具有重要意义.在主流冗余结构中,二乘二取二以其高可靠性和高安全性被广泛应用于国内外计算机联锁系统,但其核心技术被国外掌握,国内对基于该结构下的维护策略,冗余通信,联锁软件冗余等问题的研究仍显不足.为了获得更高的可靠性和安全性,本文针对二乘二取二计算机联锁系统展开研..._计算机联锁冗余方式哪个可靠性和安全性高
文章浏览阅读188次。希腊文 Chromium 的本意是 "颜色"。1797年,法国化学家 L.N.Vauquelin 在西伯利亚红铅矿中发现一种新矿物,命名为 Chromium,中文的意思是铬,铬的化合物都有颜色Python解释器的安装步骤。铬是一种质地极其坚硬的银白色金属。2006年,谷歌把一款全新的浏览器命名为 Chromium ,并向全世界开放了源代码。现在 Chromium 成为世界上许多浏览器的坚强核心,占据了70%以上的电脑屏幕。浏览器 调试 JS。_uc浏览器 chrome csdn
文章浏览阅读670次。oracle常用经典SQL查询 常用SQL查询: 1、查看表空间的名称及大小 selectt.tablespace_name, round(sum(bytes/(1024*1024)),0) ts_sizefromdba_tablespaces t, dba_data_files dwheret.tablespace_name = d.tablespace_name_用oracle sql语句 查询 热门t
文章浏览阅读826次。<!DOCTYPE html><html lang="en"><head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Document</titl..._vue页面复用按钮无效
文章浏览阅读2.5k次。前述: 在写这篇笔记之前,对笔记中的设计模式进行介绍: 本篇笔记中将要使用到的设计模式是:装饰(包装)设计模式 (1)装饰(包装)设计模式口诀: ①定义一个类,实现被装饰对象的接口 ②定义一个成员变量,记住被装饰对象的引用 ③定义构造_增加过滤器后中文变成了ascii
文章浏览阅读819次,点赞13次,收藏8次。SIT报告
文章浏览阅读413次。最近Xcode版本升级到10之后,运行项目时出现library not found for -lstdc++.6.0.9错误。项目中有用到libstdc++、libstdc++.6、libstdc++6.0.9这三个库文件的Xcode10谨慎更新报错原因是:使用之前的Xcode版本开发的项目中有用到libstdc++、libstdc++.6、libstdc++6.0.9这三个库文件,而Xcod..._-lstdc++.6.0.9
文章浏览阅读2.2k次。1.在app.config.js中的window配置项的内容替换为:"navigationStyle":"custom"custom表示自定义导航栏,但会保留右上角胶囊按钮。window: { // backgroundTextStyle: 'light', // navigationBarBackgroundColor: '#fff', // navigationBarTitleText: 'WeChat', // navigationBarTextStyle: _taro navigationstyle
文章浏览阅读1.1k次,点赞21次,收藏13次。本系列文章致力于用最简单的语言讲解Transformer架构,帮助朋友们理解它的强大,本文是第六篇:Transformer自注意力机制图文详解。_transformer 自注意力机制