视频演示:
https://www.bilibili.com/video/BV1BT4y1E7Nh/?p=12
一起来完成以下步骤:
- 引用之前的工程代码
- 创建员工信息interface和员工数组array
- 生成token
- 校验token是否正确
- 运行命令: deno run --allow-net --allow-read main.ts
import { Context } from "https://deno.land/x/oak/mod.ts";
import { key } from "../middlewares/key.ts";
//引入jwt 模块功能
import { makeJwt, setExpiration, Jose, Payload } from "https://deno.land/x/djwt/create.ts"
import employees from "../models/employees.ts";
//获取工程目录方法
const { cwd } = Deno;
//jwt头部
const header: Jose = {
alg: "HS256",
typ: "JWT",
}
/**
* 定义Controller
*/
class Controller {
/**
* 首页
* @param ctx
*/
static async hello(ctx: any) {
//cwd获取当前工程目录
//注意 ' !== `
ctx.render(`${cwd()}/views/index.ejs`, {
title: "Testing",
data: { name: " Deepincoding" }
});
}
//游客
static async guest(ctx: Context) {
ctx.response.body = "Hi Guest";
}
//获取token
static async token(ctx: Context) {
//获取员工信息
const { value } = await ctx.request.body();
console.log({ value });
//检查员工是否存在
const hadEmployee = employees.find(employee => {
return employee.username === value.username && employee.password === value.password;
});
if (hadEmployee) {
//JWT body 可以放任何你想放的内容
const payload: Payload = {
iss: hadEmployee.username,
exp: setExpiration(new Date().getTime() + 60000),
}
//生成JWT
const jwt = makeJwt({ key, header, payload });
ctx.response.status = 200;
//返回
ctx.response.body = {
id: hadEmployee.id,
username: hadEmployee.username,
jwt,
}
} else {
ctx.response.status = 422;
//返回提示信息
ctx.response.body = {
message: 'Invalid username or password'
};
}
}
//需要token才能访问admin
static async admin(ctx: Context) {
ctx.response.body = "Hi Admin";
}
}
//导出Controller
export default Controller;
middlewares/authMiddleware.ts
import { Context } from "https://deno.land/x/oak/mod.ts";
import { validateJwt } from "https://deno.land/x/djwt/validate.ts"
import { key } from "./key.ts";
//定义 authMiddleware 检查token有效性
const authMiddleware = async (ctx: Context, next: any) => {
//token 放在header里面传过来
const headers: Headers = await ctx.request.headers;
const authorization = headers.get('Authorization')
// 传过来的token是否以bearer开头 + 空格
if (!authorization || !authorization.split(' ')[1] ) {
ctx.response.status = 401;
return;
}
const jwt = authorization.split(' ')[1];
//校验token
const isValidateJwt = await validateJwt(jwt, key);
//如果token正确,程序继续往下走,否则返回401
if (isValidateJwt.isValid) {
await next();
return;
}
ctx.response.status = 401;
ctx.response.body = { message: 'Invalid jwt token' };
}
export default authMiddleware;
models/employee.ts
//定义interface
export interface Employee{
id: string,
username: string,
password: string
}
//初始化员工列表
const employees: Array<Employee> =[
{
id: "1",
username: "michael",
password: "123456"
},
{
id: "2",
username: "alex",
password: "654321"
}
]
//导出
export default employees;
routers/router.ts
//引入 Router
import { Router } from "https://deno.land/x/oak/mod.ts";
//引入自定义Controller
import Controller from "../controllers/Controller.ts";
import authMiddleware from "../middlewares/authMiddleware.ts";
//创建 router
const router = new Router();
//首页uri
router.get("/",Controller.hello);
//不需要token可以访问guest
router.get("/guest",Controller.guest);
//根据用户名和密码获取token
router.post("/token",Controller.token);
//这里加上token校验的方法
router.get("/admin",authMiddleware,Controller.admin);
//导出 router
export default router;
main.ts
//引入 Application
import { Application } from "https://deno.land/x/oak/mod.ts"
//引入页面渲染模块
import {viewEngine,engineFactory,adapterFactory} from "https://deno.land/x/view_engine/mod.ts";
//引入 router
import router from "./routers/router.ts";
//获取页面引擎
const ejsEngine = engineFactory.getEjsEngine();
//获取oak适配器
const oakAdapter = adapterFactory.getOakAdapter();
// 创建app
const app = new Application();
// 应用页面渲染引擎
app.use(viewEngine(oakAdapter,ejsEngine));
//应用 router
app.use(router.routes());
app.use(router.allowedMethods());
//log日志
console.log("Server Port 8000");
await app.listen({port: 8000 })