Simonzhangs' blog Simonzhangs' blog
首页
  • 前端文章

    • HTML
    • CSS
    • JavaScript
  • 学习笔记

    • 《JavaScript教程》
    • 《JavaScript高级程序设计》
    • 《ES6 教程》
    • JS设计模式总结
  • 《Vue》
  • 《React》
  • 《TypeScript 从零实现 axios》
  • TypeScript
  • 技术文档
  • GitHub技巧
  • Nodejs
  • 博客搭建
  • apple music
  • extension
  • 学习
  • 面试
  • 心情杂货
  • 实用技巧
  • 友情链接
关于
收藏
  • 分类
  • 标签
  • 归档
GitHub (opens new window)

Simonzhangs

前端学习探索者
首页
  • 前端文章

    • HTML
    • CSS
    • JavaScript
  • 学习笔记

    • 《JavaScript教程》
    • 《JavaScript高级程序设计》
    • 《ES6 教程》
    • JS设计模式总结
  • 《Vue》
  • 《React》
  • 《TypeScript 从零实现 axios》
  • TypeScript
  • 技术文档
  • GitHub技巧
  • Nodejs
  • 博客搭建
  • apple music
  • extension
  • 学习
  • 面试
  • 心情杂货
  • 实用技巧
  • 友情链接
关于
收藏
  • 分类
  • 标签
  • 归档
GitHub (opens new window)
  • 技术文档

  • GitHub技巧

  • Nodejs

    • 《Node教程》笔记
    • Node基础
    • Koa框架基础
    • Nunjucks模板入门
    • nunjucks模板语法
    • 基于koa与nunjucks实现cookie与session
    • nodejs递归读取所有文件
    • moduleexports和exports区别
  • 博客搭建

  • Ajax

  • 计算机网络

  • 计算机编译原理

  • 涨知识

  • 技术
  • Nodejs
simonzhangs
2022-04-01

基于koa与nunjucks实现cookie与session

# 一、cookie 与 session概述

会话(Session)跟踪是Web程序中常用的技术,用来跟踪用户的整个会话。常用的会话跟踪技术是Cookie与Session。Cookie通过在客户端记录信息确认用户身份,Session通过在服务端记录信息确认用户身份。

在用户登陆一个网站时候,网站通常会保持登陆状态持续一定的时间,这个就是会话跟踪技术的应用之一。

# 二、Cookie

Cookie是服务端发给客户端的凭证,不需要服务器记录;

Session是服务端存储的关于确认客户端的凭证,客户端的Cookie是用来验证客户端的真实性。

网站服务器程序可以在浏览器中写入cookie,然后浏览器再次访问这个网站时,就会带着这个cookie;示例代码为以koa框架创建的web服务器:

router.get('/', async ctx => {
    // cookie是以明值对的方式记录在客户端(浏览器)的
    ctx.cookies.set('username', 'simonzhangs')
    ctx.body = 'cookie'

})
1
2
3
4
5
6

写入cookie之后,这个浏览器再次访问这个网站的任何一个页面,都会带着这个cookie。

可以通过下面方法获取cookie:

router.get('/test', async ctx => {
    let username = ctx.cookies.get('username')
    ctx.body = username;
})
1
2
3
4

通过maxAge可以设置cookie过期的毫秒数:

ctx.cookies.set('username', 'simonzhangs', {
        maxAge: 5000
})
1
2
3

通过cookie来记录网页访问量:

router.get('/test', async ctx => {
    let count = ctx.cookies.get('count');
    if(count) {
        ++count;
        ctx.cookies.set('count', count);
    } else {
        count = 1;
        ctx.cookies.set('count', 1);
    }
    ctx.body = count;
})
1
2
3
4
5
6
7
8
9
10
11

# 三、Session

利用cookie在客户端存储数据是明值对、完全透明的,如果存储一些用户信息,会导致很严重的安全问题,所以为了记录用户的登陆状态,需要使用cookie与session结合的方式。

利用koa的中间件koa-session: npm i --save koa-session; 引入并使用:

const session = require('koa-session') //引入
// 配置使用
const app = new Koa();

app.keys = ['123456']
app.use(session({
    maxAge:10000,
}, app))
1
2
3
4
5
6
7
8

设置session:

router.get('/session', async ctx => {
    ctx.session.username = 'admin';
    ctx.body = 'set session';
})
1
2
3
4

获取session:

router.get('/session_test', async ctx => {
    let username = ctx.session.username;
    ctx.body = username;
})
1
2
3
4

在设置session时,session内容保存在服务端,同时发送cookie到客户端,这个cookie是一串密钥,用于在请求服务端数据时对用户身份的确认。

同样可以利用session来记录网页访问次数:

router.get('./session', async ctx => {
    if(ctx.session.count) {
        ctx.session.count++;
    } else {
        ctx.session.count = 1;
    }
    ctx.body = ctx.session.count;
})
1
2
3
4
5
6
7
8

# 四、登陆验证

利用koa与nunjucks实现session与cookie结合来模拟用户登陆过程,要求能达到:

  • 首页:任何用户都可以访问;
  • 登陆页:任何用户都可以访问;
    • 未登录时,为登陆表单;
    • 登录后,提示已登陆成功;
  • 内容页:只有登陆成功后才可以访问;
  • 注销:登陆后可以选择注销;
  • 登陆后,任何一个页面都可以显示用户名。

首先安装项目所用依赖包,并在server.js中引入并使用:

const Koa = require('koa');
const views = require('koa-views');
const router = require('koa-router')()
const nunjucks = require('nunjucks')
const parser = require('koa-parser')
const session = require('koa-session')

const app = new Koa();
// session密钥及seesion使用
app.keys = ['123456']
app.use(session({
    maxAge:30*1000,
}, app));
// koa的post请求内容解析
app.use(parser());
// nunjucks 页面模板路径配置
app.use(views(__dirname + '/views', {
    map:{html: 'nunjucks'}
}))
// 页面路由
app.use(router.routes())

app.listen(3000, () => {
    console.log('server is running');
})
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25

然后在views文件夹下,新建需要用的页面:

  1. 公共页面部分:layout.html
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<body>
    <div>
        <a href="/">首页</a>
        <a href="/list">列表</a>
        <a href="/login">登陆</a>
    </div>
    {% block content %}
    {% endblock %}
</body>
</html>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
  1. 首页:home.html
{% extends './views/layout.html' %}
{% block content %}
<h1>首页</h1>
<p>Hello,{{user}}</p>
{% endblock %}
1
2
3
4
5
  1. 登陆页面:login.html
{% extends './views/layout.html' %}
{% block content %}
{% if isLogin %}
<p>您已经登陆!! {{isLogin}} </p>
{% else %}
<form action="/login" method="post">
    <input type="text" name="username" id="">
    <input type="password" name="password" id="">
    <input type="submit" value="登录">
</form>
{% endif %}
{% endblock %}
1
2
3
4
5
6
7
8
9
10
11
12

4.登陆后才可以访问的页面:list.html

{% extends './views/layout.html' %}
{% block content %}
<h1>列表</h1>
<p>Hello,{{user}}</p>
<a href="/logout">注销</a>
{% endblock %}
1
2
3
4
5
6

然后在server.js中配置路由信息和逻辑:

// 首页:任何用户都可以访问
router.get('/', async ctx => {
    let user = ctx.session.user
    await ctx.render('home.html',{
        user
    })
})
1
2
3
4
5
6
7
//登陆页:任何用户都可以访问,表单
router.get('/login', async ctx => {
    let isLogin = false;
    if(ctx.session.user){
        isLogin = true;
    }
    await ctx.render('login.html', {
        isLogin
    });
})
1
2
3
4
5
6
7
8
9
10
//登陆页表单post
router.post('/login', async ctx => {
    let username = ctx.request.body.username;
    let password = ctx.request.body.password;
    if (username === 'admin' && password === '123456') {
        ctx.session.user = 'admin'
        // 重定向
        ctx.redirect('./list');
    } else {
        ctx.redirect('/')
    }
})
1
2
3
4
5
6
7
8
9
10
11
12
// 内容页:只有登陆成功后才可以访问
router.get('/list', async ctx => {
    if (ctx.session.user) {
        let user = ctx.session.user
        await ctx.render('list.html',{
            user
        });
    }else {
        ctx.redirect('/');
    }
})
1
2
3
4
5
6
7
8
9
10
11
// 注销
router.get('/logout', async ctx => {
    ctx.session.user = '';
    ctx.redirect('/');
})
1
2
3
4
5
编辑 (opens new window)
上次更新: 2022/04/01, 21:54:01
nunjucks模板语法
nodejs递归读取所有文件

← nunjucks模板语法 nodejs递归读取所有文件→

最近更新
01
一些有意思的类比
06-16
02
the-super-tiny-compiler解析
06-06
03
计算机编译原理总概
06-06
更多文章>
Theme by Vdoing | Copyright © 2021-2022
蜀ICP备2021023197号-2
Simonzhans | MIT License
  • 跟随系统
  • 浅色模式
  • 深色模式
  • 阅读模式
  • 飙升榜
  • 新歌榜
  • 云音乐民谣榜
  • 美国Billboard榜
  • UK排行榜周榜