Secbone / koa-session2

Middleware for Koa2 to get/set session
MIT License
153 stars 30 forks source link

how to use custom storesr. #14

Closed hezhongfeng closed 8 years ago

hezhongfeng commented 8 years ago

Store.js

import Redis from "ioredis";
import {Store} from "koa-session2";

export default class RedisStore extends Store {
  constructor() {
    super();
    this.redis = new Redis();
  }

  async get(sid) {
    return await this.redis.get(`SESSION:${sid}`);
  }

  async set(session, opts) {
    if (!opts.sid) {
      opts.sid = this.getID(24);
    }
    await this.redis.set(`SESSION:${opts.sid}`, session);
    return opts.sid;
  }

  async destroy(sid) {
    return await this.redis.del(`SESSION:${sid}`);
  }
}

when I use sessoin to store others,it doesn't work. For example: when I login succeed,I want to store the user's information. but when I want get it from session,it is "undefined". But when I didn't use redis,it work well.

  //update session
  ctx.session.user = userInfo;

get user information at other get request,it is "undefined"

console.log(ctx.session.user);
Secbone commented 8 years ago

Any case could you show me? You can check if any cookie is set in browser and you got the correct cookie in server side. Maybe you can check my test case here

hezhongfeng commented 8 years ago

@Secbone I could check the cookie id in browaer and redis.It's same. But the user's information isn't storied in redis. I don't know why.

import session from "koa-session2";
import Store from "./models/store";
...
app.use(session({
  store: new Store(),
  maxAge: 1000 * 60 * 60 * 24,
}));
Secbone commented 8 years ago

what is the value of the "SESSION:${id}" in your redis? "", {} or something else?

hezhongfeng commented 8 years ago

@Secbone I use keys *to show the ID It'sSESSION:n5hbppq7BI1cZBEi-xgO-zvQvixGWr8g just this.

Secbone commented 8 years ago

get SESSION:n5hbppq7BI1cZBEi-xgO-zvQvixGWr8g ?

hezhongfeng commented 8 years ago

YES @Secbone

Secbone commented 8 years ago

Can you share me the code on Github or anywhere else?

hezhongfeng commented 8 years ago

@Secbone It's store.js.

import Redis from "ioredis";
import {Store} from "koa-session2";

export default class RedisStore extends Store {
  constructor() {
    super();
    this.redis = new Redis();
  }

  async get(sid) {
    return await this.redis.get(`SESSION:${sid}`);
  }

  async set(session, opts) {
    if (!opts.sid) {
      opts.sid = this.getID(24);
    }
    await this.redis.set(`SESSION:${opts.sid}`, session);
    return opts.sid;
  }

  async destroy(sid) {
    return await this.redis.del(`SESSION:${sid}`);
  }
}

app.js

import session from "koa-session2";
import Store from "./models/store";
...
app.use(session({
  store: new Store(),
  maxAge: 1000 * 60 * 60 * 24,
}));

login.js

  const userInfo = await User.getUserByEmail(data.email);
  //update session
  ctx.session.user = userInfo;
  message.result = true;
  ctx.body = message;

home.js

  await ctx.render('home', {
    session: ctx.session,
  });

The only difference is that

app.use(session({
  store: new Store(),
  maxAge: 1000 * 60 * 60 * 24,
}));

or

app.use(session({
  //store: new Store(),
  maxAge: 1000 * 60 * 60 * 24,
}));
Secbone commented 8 years ago

Your session is an object, and redis can only accept a value of String, so that you should change your session to JSON type, like this:

redis.set(`SESSION:${opts.sid}`, JSON.stringify(session));

...

let data = await redis.get(`SESSION:${sid}`);
session = JSON.parse(data);
hezhongfeng commented 8 years ago

@Secbone Thank you. It work well.