用koa-session实现登录状态验证

本文共有2864个字,关键词:koakoa-session

每个用户登录后,需要保持登录状态,某些特定的页面需要用户登录后才能访问。通过了解,nodejs中可以用koa-session进行认证。下面就讲下我用过的理解。

我是用koa来搭建我的网站的,所以很自然的就想到用koa-session来做验证,至于其他的做法也不是很了解。

koa-session实际上是通过cookie来保存信息的。koa-session在服务器上生成一个信息,通过加密后,以cookie的形式发送到用户的浏览器,在用户浏览器上可以看到是一个加密的cookie字段,形如:

然后在服务端路由中通过ctx.session.xx来获取xx这个信息。而当每次当用户发送请求时候,就可以获取到这个cookie,koa-sesscion会内部会帮我们解密为最初的存储的信息,于是我们可以通过判断这个cookie是存在合来校验用户是否已经登录了。

一、在app.js中使用koa-session

const Koa = require('koa');
const bodyParser = require('koa-bodyparser');
const session=require('koa-session');
const app = new Koa();
 app.keys = ['this is my secret and fuck you all'];//我理解为一个加密的密钥

app.use(session({
  key: 'koa:sess', /** cookie的名称,可以不管 */
  maxAge: 7200000, /** (number) maxAge in ms (default is 1 days),cookie的过期时间,这里表示2个小时 */
  overwrite: true, /** (boolean) can overwrite or not (default true) */
  httpOnly: true, /** (boolean) httpOnly or not (default true) */
  signed: true, /** (boolean) signed or not (default true) */
},app));

app.use(bodyParser());

二、定义登录的路由

module.exports = {
    'POST /login': async (ctx, next) => {
        var username= ctx.request.body.username;
        var password = ctx.request.body.password;
        if (username=='123'&&password==='123') {
             //保存登录状态,这句代码会在浏览器中生成一个cookie
            ctx.session.user = username;
            ctx.body = { success: true, msg: '登录成功!' };
        }
        else{
            ctx.body = { success: false, msg: '账号或密码错误!' };
        }

    }
};

这里定义一个/login的登录接口,浏览器可以通过Ajax来调用这个接口进行登录,调接口时需传用户名(username)和密码(password),这里提供一个前端jquery调用的示例:

var username = '123'
var password = '123456'
// jquery的post请求方法
$.post('/login', { username: username, password: password }, function (data) {
    if (data.success) {
        // 登录成功
        console.log(data.msg);
    } else {
        // 登录失败,弹出失败信息。
        alert(data.msg); 
    }
});

三、校验是否已经登录

比如访问/home这个路由是需要登录的,在浏览器中直接输入www.your-domin.com/home
,如果已经检测到是未登录,则应该跳转到登录页。

module.exports = {
    'GET /home': async (ctx, next) => {
        // 我们前面登录时存了ctx.seesion.user这个值
        // 所以可以校验,ctx.session.user不存在则跳转到登录页面
        if (!ctx.session.user) {
            ctx.response.redirect('/login');
        }
        // 已登录,则继续渲染页面
        ctx.render('home.html', {
            title: 'home'
        });
     }
};

四、退出登录

咱们定义一个退出登录的路由,在这个路由里将登录时存的信息给清空掉即可,如/logout

module.exports = {
    'GET /logout': async (ctx, next) => {
        // 将登录信息清空
        ctx.session = null;
        // 跳转到登录页或网站首页
        ctx.response.redirect('/');
    }
};

五、总结

koa-session使得我们可以很方便地做验证登录,它内部帮我们做了信息的加密和解密,在浏览器中看到的信息是一串类似uuid的乱码,所以安全性是不错的。

「一键投喂 软糖/蛋糕/布丁/牛奶/冰阔乐!」

fengxianqi

(๑>ڡ<)☆谢谢老板~

使用微信扫描二维码完成支付

版权声明:本文为作者原创,如需转载须联系作者本人同意,未经作者本人同意不得擅自转载。
添加新评论
已有 15 条评论
    1. fengxianqi: 回复 @kiwi

      恭喜你是本blog的第一个评论哈哈哈

  1. 。。。:

    博主,你这用户session信息存在了,你还重定向。。。

    1. fengxianqi: 回复 @。。。

      你真细心,谢谢指出,已改正啦。

  2. test:

    9999.09.09.09.09.09

  3. 大将军:

    请问你前台怎么写, var username= ctx.request.body.username;怎么获取用户名de

    1. fengxianqi: 回复 @大将军

      前台ajax请求就可以了。比如jQuery可以这样:

      var username = '123'
      var password = '123456'

      $.post('/login', { username: username, password: password }, function (data) {

      if (data.success) { console.log(data.msg) } else { alert(data.msg); }

      });

      1. 大将军: 回复 @fengxianqi

        谢谢大佬,现在不知怎样从前台把session取出来,显示用户名

        1. fengxianqi: 回复 @大将军

          一般不能直接使用,因为是加密的。
          在用户登陆后:
          ctx.session.user = username;
          这句会在浏览器中插入一个名为"koa:sess"的cookie,是加密的,在前台不建议提供解密方法去解密。

          如果想要在前台存储用户姓名等信息,可以在登陆成功后手动设置到cookie,localstorage或者sessionStorage中。
          比如设置到localStorage中:window.localStorage.setItem('username', '123');
          从localStorage中获取username: localStorage.getItem('username');

  4. 111:

    111

  5. 没人发:

    怎么退出登录状态呢?

    1. fengxianqi: 回复 @没人发

      退出登录的部分我已更新在文章中哈

  6. 小火:

    我用为什么在别的接口 获取不到登录时设置的 session 呢?

    1. fengxianqi: 回复 @小火

      注意是否有用ctx.session.user = username;给客户端设置cookie,可以浏览器F12检查一下

      1. 小火: 回复 @fengxianqi

        恩恩 ,我这在登录设置了一个session
        rolling和renew都设置了true想保持session会话
        但是并没有起作用 这是为什么?