視頻演示:https://www.bilibili.com/video/BV1BT4y1E7Nh/?p=13
一起來完成以下步驟:
-
先來看我們要達到的效果————不登錄將不能訪問/home首頁.
-
登錄和退出功能已經提前寫好
-
添加session,登錄成功後把員工信息放到session中.退出時,要清空session
-
添加authMiddlewares,在session有效的情況下才能訪問/home頁面,否則調轉到登錄頁面
-
運行命令: deno run --allow-net --allow-read main.ts
#controllers/controller.ts
//引入後臺REDIRECT
import { Context, REDIRECT_BACK } from "https://deno.land/x/oak/mod.ts";
//解析Form
import { multiParser } from 'https://raw.githubusercontent.com/deligenius/multiparser/master/mod.ts'
//引入員工列表
import employees from "../models/employees.ts";
//獲取工程目錄
const { cwd } = Deno;
class Controller {
//默認登錄頁面
static async login(ctx: any) {
ctx.render(`${cwd()}/views/login.ejs`, {
msg: ""
});
}
//提交登錄Action
static async logon(ctx: any) {
//獲取員工登錄信息
const strLoginEmployee = JSON.stringify(await multiParser(ctx.request.serverRequest));
const jsonLoginEmployee = JSON.parse(strLoginEmployee);
//檢查登錄員工是否存在
const hadEmployee = employees.find(employee => {
return employee.username === jsonLoginEmployee.username && employee.password === jsonLoginEmployee.password;
});
//如果存在
if (hadEmployee) {
//把員工set到session裏面
await ctx.state.session.set("EMPLOYEE_SESSION", hadEmployee);
ctx.response.redirect(REDIRECT_BACK, "/home");
} else {
//如果不存在,將在登錄頁面顯示錯誤信息
ctx.render(`${cwd()}/views/login.ejs`, {
msg: "用戶名或密碼錯誤"
});
}
}
//登錄成功後跳轉到首頁
static async home(ctx: any) {
let sessionName: string = " is null";
//獲取session
const hadEmployee = await ctx.state.session.get("EMPLOYEE_SESSION");
//session 是否存在員工信息
if (hadEmployee !== undefined) {
sessionName = hadEmployee.username;
}
//再首頁顯示員工名稱
ctx.render(`${cwd()}/views/home.ejs`, {
usersession: sessionName
});
}
//退出登錄
static async logout(ctx: any) {
//這裏清空session
await ctx.state.session.set("EMPLOYEE_SESSION", undefined);
ctx.response.redirect(REDIRECT_BACK, "/");
}
}
export default Controller;
#middlewares/authMiddleware.ts
import { Context,REDIRECT_BACK } from "https://deno.land/x/oak/mod.ts";
//定義 authMiddleware 檢查session有效性
const authMiddleware = async (ctx: any, next: any) => {
//檢查session 是否存在
const hadEmployee = await ctx.state.session.get("EMPLOYEE_SESSION");
if(hadEmployee !== undefined){
await next();
return;
}
//否則調到login頁面
ctx.response.redirect(REDIRECT_BACK, "/");
}
export default authMiddleware;
#models/employee.ts
//定義interface
export interface Employee{
id: string,
username: string,
password: string
}
//初始化員工列表
const employees: Array<Employee> =[
{
id: "1",
username: "admin",
password: "123456"
},
{
id: "2",
username: "alex",
password: "654321"
}
]
//導出
export default employees;
#routers/router.ts
import { Router } from "https://deno.land/x/oak/mod.ts";
import Controller from "../controllers/Controller.ts";
import authMiddleware from "../middlewares/authMiddleware.ts";
const router = new Router();
//默認登錄頁面
router.get("/",Controller.login);
//點擊登錄按鈕
router.post("/logon",Controller.logon);
//登錄成功跳轉到首頁,如果session不存在,將跳轉到登錄頁面
router.get("/home",authMiddleware,Controller.home);
//退出登錄
router.get("/logout",Controller.logout);
export default router;
#main.ts
//引入Application,send組件
import { Application, send } from "https://deno.land/x/oak/mod.ts"
//顯示頁面,必須引入這3個功能
import { viewEngine, engineFactory, adapterFactory } from "https://deno.land/x/view_engine/mod.ts";
import router from "./routers/router.ts";
import { Session } from "https://deno.land/x/session/mod.ts";
//獲取頁面模板引擎,這裏是ejs
const ejsEngine = engineFactory.getEjsEngine();
//獲取oak適配器 oakAdapter
const oakAdapter = adapterFactory.getOakAdapter();
//創建app
const app = new Application();
//我們工程使用的是oak
const session = new Session({ framework: "oak" });
//初始化session
await session.init();
//引用session
app.use(session.use()(session));
//創建viewEngine並應用到app
app.use(viewEngine(oakAdapter, ejsEngine));
app.use(router.routes());
app.use(router.allowedMethods());
//必須加上靜態文件所有在目錄,例如static
app.use(async ctx => {
await send(ctx, ctx.request.url.pathname, {
root: `${Deno.cwd()}/static`
});
});
console.log("Server Port 8000");
//端口
await app.listen({ port: 8000 })
#views/login.ejs
<form action="/logon" enctype="multipart/form-data" method="POST">
<div class="input-group mb-3">
<input type="text" class="form-control" name="username" placeholder="username">
<div class="input-group-append">
<div class="input-group-text">
<span class="fas fa-envelope"></span>
</div>
</div>
</div>
<div class="input-group mb-3">
<input type="password" class="form-control" name="password" placeholder="Password">
<div class="input-group-append">
<div class="input-group-text">
<span class="fas fa-lock"></span>
</div>
</div>
</div>
<div class="row">
<div class="col-8">
<div class="icheck-primary">
</div>
</div>
<!-- /.col -->
<div class="col-4">
<button type="submit" class="btn btn-primary btn-block">Sign In</button>
</div>
<!-- /.col -->
</div>
</form>