secbone / koa-session2 Goto Github PK
View Code? Open in Web Editor NEWMiddleware for Koa2 to get/set session
License: MIT License
Middleware for Koa2 to get/set session
License: MIT License
Hello,
interesting lib. With better docs in comparison with koa/session.
I'm struggling to share a context while working with graphQL app.
There, I have to set a token after performing login mutation (based on user data).
I wasn't able to do so with koa/session as the only property I could change was maxAge
Is there a demo
branches node6
package.json:
"main": "dist/index.js",
==>
"main": "index.js",
Please help me?
Beside the fact the destroy function is currently called destory, neither one nor the other (destory / destroy) seems to get called when the ctx.logout() method is triggered (as part of Koa-Passport). I don't know if it's because the function is currently not called correctly, or whether I'm missing anything else.
it seems linke no session-mongo middleware coudle be used in koa2
need_refresh = false
ctx.session.refresh = () => {need_refresh = true}
need_refresh has no let or var ,it's may be global
node_modules/koa-session2/dist/index.js:125
var ref = _asyncToGenerator(regeneratorRuntime.mark(function _callee(sid) {
^
ReferenceError: regeneratorRuntime is not defined
only redis example ?
Is it possible to get sessions working with the client without cookies? For instance, rather than using cookies in a browser-led GET
, is it possible to use POST
with JSON content? We have a project that we would like to release a React Native client for, and cookies are not ideal.
Basically the title, I'll try to make a pull request as fast as I can.
When a session key already exists in the browser and is sent to the server the session key is reused. Is this the indented behaviour?
Best Regards
Anton
when i use koa-session2 with koa-passport 6.0,I got the error:
req.session.regenerate is not a function
It seems to be because of this jaredhanson/passport#907
import {Store} from "koa-session2"
这样引不到 Store 文件
然后我是这样引的
import Store from 'koa-session2/libs/store'
然后extend 的时候还是会报错,只能把store.js 里 的 class Store用es6的 export 导出
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);
I got this error when try to use your package:
/opt/node/app/web/server/util/session-store/index.js:31
var _this = _possibleConstructorReturn(this, (RedisStore.__proto__ || Object.getPrototypeOf(RedisStore)).call(this));
^
TypeError: Class constructor Store cannot be invoked without 'new'
at new RedisStore (/opt/node/app/web/server/util/session-store/index.js:6:17)
at Object.<anonymous> (/opt/node/app/web/server/index.js:60:10)
at Module._compile (module.js:571:32)
at loader (/opt/node/app/web/node_modules/babel-register/lib/node.js:144:5)
at Object.require.extensions.(anonymous function) [as .js] (/opt/node/app/web/node_modules/babel-register/lib/node.js:154:7)
at Module.load (module.js:488:32)
at tryModuleLoad (module.js:447:12)
at Function.Module._load (module.js:439:3)
at Module.require (module.js:498:17)
at require (internal/module.js:20:19)
at Object.<anonymous> (/opt/node/app/web/bin/server.js:1:1)
at Module._compile (module.js:571:32)
at loader (/opt/node/app/web/node_modules/babel-register/lib/node.js:144:5)
at Object.require.extensions.(anonymous function) [as .js] (/opt/node/app/web/node_modules/babel-register/lib/node.js:154:7)
at Module.load (module.js:488:32)
at tryModuleLoad (module.js:447:12)
at Function.Module._load (module.js:439:3)
at Function.Module.runMain (module.js:605:10)
at Object.<anonymous> (/opt/node/app/web/node_modules/babel-cli/lib/_babel-node.js:154:22)
at Module._compile (module.js:571:32)
at Object.Module._extensions..js (module.js:580:10)
at Module.load (module.js:488:32)
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) {
const data = await this.redis.get(`SESSION:${sid}`)
return JSON.parse(data)
}
async set(session, { sid = this.getID(24), maxAge = 1000000 } = {}) {
try {
// Use redis set EX to automatically drop expired sessions
await this.redis.set(`SESSION:${sid}`, JSON.stringify(session), 'EX', maxAge / 1000)
} catch (e) {}
return sid
}
async destroy(sid) {
return await this.redis.del(`SESSION:${sid}`)
}
}
app:
import RedisStore from './util/session-store'
app.use(session({
key: 'MY_KEY',
httpOnly: false,
store: new RedisStore()
}))
Most of the times other middlewares may have already setup external store in the context. It will be very convenient if the session store can directly access these resources.
For example
get(sid, ctx) {
return ctx.db.session.findOne({sid})
}
I used this library to store the session to redis, and I set the expiration time of the session. However, the problem was that the session was not updated in time after refreshing the page, and the session delivery in redis was still the session at the time of login, which did not change with the user's operation. I tried to add the code,ctx.session.user = player ;
and the session was not updated. Who can tell me how to do it? Thank you very much.
When the user exits, do I need to destroy session,How do you destroy your plug-in session???
If the session identifier requested by the user was not found in the session repository, a session will be created with the identifier requested by the user.
For example, when requesting a non-existent session:
Request Headers:
cookie: s=auth_admin
a session will be created with the requested name auth_admin
.
This is not secure, given that you can specify control characters in the name of the session identifier.
The correct behavior in the absence of the requested session identifier will be the assignment of a new identifier.
// destory old session
if(id) {
id = null;
return opts.store.destroy(id);
}
what's the meaning of destroying it, since id has already been set as null
When you add or update the contents of the session, there is an unnecessary update of the session, for example:
ctx.session.view = 'index_update';
ctx.session.new = 'new_param';
will create an http request with a cookie update (session).
In my opinion - this is a mistake, because session update should be performed only when calling ctx.session.refresh()
.
The current session behavior causes a lot of unnecessary session updates for any request to the engine, if, for example, with each request, it changes values such as ctx.session.last_requests
or ctx.session.count_views_page
.
I followed your demo to add my middleware, found some problem.
my code:
app.js
//if the following ,I cannt view my page;
app.use(session({store:new Store()}))
app.use(convert(session({store: new Store()})));
//the same question
// so,I have to write like this... , maybe some problem?
app.use(async (ctx, next) => { session({ store: new Store() }); await next(); });
user.js
let result = {......};
ctx.session.view = result;
TypeError: Cannot set property 'view' of undefined
at app.js:36:3
at dispatch (E:\mywork\koa2.0\node_modules\koa\node_modules\koa-compose\in dex.js:43:32)
at next (E:\mywork\koa2.0\node_modules\koa\node_modules\koa-compose\index. js:44:18)
at app.js:31:9
at [object Generator].next (native)
at step (app.js:23:1)
at app.js:23:1
at new Promise (E:\mywork\koa2.0\node_modules\runkoa\node_modules\babel-po lyfill\node_modules\core-js\modules\es6.promise.js:193:7)
at app.js:23:1
at app.js:27:9
at dispatch (E:\mywork\koa2.0\node_modules\koa\node_modules\koa-compose\in dex.js:43:32)
at next (E:\mywork\koa2.0\node_modules\koa\node_modules\koa-compose\index. js:44:18)
at E:\mywork\koa2.0\node_modules\koa-bodyparser\index.js:60:14
at run (E:\mywork\koa2.0\node_modules\runkoa\node_modules\babel-polyfill\n ode_modules\core-js\modules\es6.promise.js:89:22)
at E:\mywork\koa2.0\node_modules\runkoa\node_modules\babel-polyfill\node_m odules\core-js\modules\es6.promise.js:102:28
at flush (E:\mywork\koa2.0\node_modules\runkoa\node_modules\babel-polyfill \node_modules\core-js\modules_microtask.js:14:5)
at nextTickCallbackWith0Args (node.js:415:9)
at process._tickCallback (node.js:344:13)
can i comment the line?
if(old == JSON.stringify(ctx.session)) return;
app.use(session({
key: config.session.key,
store: new Store()
}));
all clients get same sid
opts.sid = this.getID(24);
this line just run one time
really confused
thanks for your help!
var _this = _possibleConstructorReturn(this, (RedisStore.proto || Object.getPrototypeOf(RedisStore)).call(this));
TypeError: Class constructor Store cannot be invoked without 'new'
at new RedisStore
HttpOnly set to FLASE does not work
.use(session({key: 'koa:sess', signed: true, overwrite: true, httpOnly: false}))
Does it means the time to destroy session?
I've put some console.log on login and logout and I always get a sequence of 1# get, 2# destroy, #3 set, e.g. for logout
<-- POST /api/User/logout?
getting sid SESSION:7sAWNTc02BKJE7iviPkNL7PhaqfacSDE, value: {"passport":{"user":{"_id":"5739d53fda88d2287e1f8631","username":"1234","password":null,"__v":0,"type":"User"}}}
destroying sid SESSION:7sAWNTc02BKJE7iviPkNL7PhaqfacSDE
setting sid SESSION:n-4yQqUH_q_OX9kZEhFcTlvZrmRnLDe3, value: {"passport":{}}
--> POST /api/User/logout? 200 419ms 4b
or for login:
<-- POST /api/User/login?include=user
getting sid SESSION:n-4yQqUH_q_OX9kZEhFcTlvZrmRnLDe3, value: {"passport":{}}
cb from login
destroying sid SESSION:n-4yQqUH_q_OX9kZEhFcTlvZrmRnLDe3
setting sid SESSION:n-4yQqUH_q_OX9kZEhFcTlvZrmRnLDe3, value: {"passport":{"user":{"_id":"5739d53fda88d2287e1f8631","username":"1234","password":null,"__v":0,"type":"User"}}}
--> POST /api/User/login?include=user 200 679ms 242b
Probably the logout does not need to set anything after having destroyed it, or the login does not need to destroy the session for after setting it anyway.
I think this line of code is aiming at tacking this issue, but session
is not undefined, it's just the object inside the passport
key, which is empty.
destroy(sid)
should be async destroy(sid)
module.exports = RedisStore;
when i delete session by
ctx.session = null
it throws
TypeError: Cannot convert undefined or null to object
and fix it
// if is an empty object
if(ctx.session !== null && typeof ctx.session === 'object' && !Object.keys(ctx.session).length) {
ctx.session = null;
}
example.js
const Koa = require("koa");
const session = require("koa-session2");
const Store = require("./Store.js");
const Router = require('koa-router');
const fs = require('fs')
const captcha = require("trek-captcha")
const Redis = require('ioredis')
const redis = new Redis({
port: 6379, // Redis port
host: '127.0.0.1', // Redis host
family: 4, // 4 (IPv4) or 6 (IPv6)
db: 0
});
const app = new Koa();
// body parser
const bodyParser = require('koa-bodyparser')
app.use(bodyParser())
let router = new Router();
app.use(session({
store: new Store(),
}));
async function run(){
const {token, buffer} = await captcha();
console.log(token, buffer)
}
// 请求表单
router.get('/', async (ctx, next) => {
ctx.response.body = `<h1>Index</h1>
<form action="/signin" method="post">
<p>Name: <input name="name" value="koa"></p>
<p>Password: <input name="password" type="password"></p>
<p><input type="submit" value="Submit"></p>
</form>`;
})
// 表单处理
let count = 1;
router.post('/signin', async (ctx, next) => {
ctx.session = {
count: count,
name: "bob"
}
var
name = ctx.request.body.name || '',
password = ctx.request.body.password || '';
console.log(`signin with name: ${name}, password: ${password}`);
if (name === 'koa' && password === '12345') {
ctx.response.body = `<h1>Welcome, ${name}!</h1>`;
} else {
redis.get('failcountuser:1234').then((result) => {
let resultData = JSON.parse(result);
ctx.session.user = "test1";
let user = ctx.session.user;
console.log(resultData.count);
console.log(user);
console.log(ctx.session);
});
}
})
app
.use(router.routes())
.use(router.allowedMethods());
app.listen(3000)
console.log('[demo] session is starting at port 3000')
Store.js
const Redis = require("ioredis");
const { Store } = require("koa-session2");
class RedisStore extends Store {
constructor() {
super();
this.redis = new Redis({
port: 6379,
host: "127.0.0.1",
family: 4,
db: 0,
}
);
}
async get(sid) {
let data = await this.redis.get(`SESSION:${sid}`);
return JSON.parse(data);
}
async set(session, { sid = this.getID(24), maxAge = 1000000 } = {}) {
try {
// Use redis set EX to automatically drop expired sessions
// await this.redis.set(`SESSION:${sid}`, JSON.stringify(session), 'EX', maxAge / 1000);
await this.redis.set(`failcountuser:1234`, JSON.stringify(session), 'EX', maxAge / 10);
} catch (e) {}
return sid;
}
async destroy(sid) {
return await this.redis.del(`SESSION:${sid}`);
}
}
module.exports = RedisStore;
然后我在redis-cli查看failcountuser:1234
,没有看见user:test1这个字段
Store.js uses the default Redis connection.
Add this change to allow custom configuration:
Store.js
constructor(opts) {
super();
this.redis = new Redis(opts);
}
main.js
app.use(session({
store: new Store({
host: some.host.or.ip
})
}));
In version 2.2.10, there is an error.
In index.js there is a call with:
id = await store.getID(24);
But in store.js
the function getID
is not a promise:
getID(length) {
Result is:
TypeError: store.getID is not a function
at /opt/aplus/dev/server/node_modules/koa-session2/index.js:17:34
I got this error when try to destroy a session:
TypeError: ctx.session.destroy is not a function
app:
ctx.session.destroy();
Why not give a destroy()
method to Session?
And how can I destroy a session simply?
With todays release of koa 2.0.1
do you plan to release node7 branch as latest anywhere soon?
Thank you!
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.