Skip to content

Commit 70a3a6f

Browse files
authored
🔀 Merge pull request #126 from leancloud/koa
🐛 修复 `AV.Cloud.HttpsRedirect` 在 koa 中会出现循环重定向的问题
2 parents fb122fc + 6413f6c commit 70a3a6f

13 files changed

Lines changed: 271 additions & 180 deletions

CHANGELOG.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,9 @@
11
# 更新日志
22

3+
## v3.1.1
4+
5+
- 修复 `AV.Cloud.HttpsRedirect` 在 koa 中会出现循环重定向的问题。
6+
37
## v3.1.0
48

59
- `AV.Express()` 添加 `onError`(全局云函数错误处理)和 `ignoreInvalidSessionToken`(忽略不正确的 Session Token 而不是返回错误)选项。

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
npm install --save leanengine leancloud-storage@3 --save
77
```
88

9-
建议使用 Node.js 6.0 以上的版本(可在 `package.json` 中设置 `engines.node``6.x`)。
9+
建议使用 Node.js 8.0 以上的版本(可在 `package.json` 中设置 `engines.node``8.x`)。
1010

1111
## 文档
1212

lib/frameworks.js

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,8 @@ function express(middleware) {
44

55
function koa(middleware) {
66
return function*(next) {
7+
this.req.secure = this.secure; // used by cookie-session
8+
79
yield middleware.bind(null, this.req, this.res);
810

911
if (this.req.currentUser) {
@@ -33,6 +35,8 @@ function koa(middleware) {
3335
function koa2(middleware) {
3436
return function(ctx, next) {
3537
return new Promise( (resolve, reject) => {
38+
ctx.req.secure = ctx.secure; // used by cookie-session
39+
3640
middleware(ctx.req, ctx.res, err => {
3741
if (ctx.req.currentUser) {
3842
ctx.currentUser = ctx.req.currentUser;

package.json

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "leanengine",
3-
"version": "3.1.0",
3+
"version": "3.1.1",
44
"description": "LeanCloud LeanEngine Node.js SDK.",
55
"repository": {
66
"type": "git",
@@ -29,10 +29,11 @@
2929
"leancloud-storage": "^3.0.0"
3030
},
3131
"keywords": [
32-
"LeanCloud",
33-
"LeanEngine",
32+
"leancloud",
33+
"leanengine",
3434
"cloud",
35-
"BaaS"
35+
"express",
36+
"koa"
3637
],
3738
"config": {
3839
"blanket": {
@@ -53,7 +54,7 @@
5354
"test": "npm install --no-save leancloud-storage@3 && npm-run-all test-tsd test-express test-koa1 test-koa2",
5455
"test-express": "mocha test test/express",
5556
"test-tsd": "tsc leanengine.d.ts",
56-
"test-koa1": "env FRAMEWORK=koa npm install --no-save leancloud-storage@3 koa@1 koa-bodyparser@2 && mocha test test/koa",
57-
"test-koa2": "env FRAMEWORK=koa npm install --no-save leancloud-storage@3 koa@2 koa-bodyparser@4 && mocha test test/koa test/koa2"
57+
"test-koa1": "npm install --no-save leancloud-storage@3 koa@1 koa-bodyparser@2 && env FRAMEWORK=koa KOA_VER=1 mocha test test/koa",
58+
"test-koa2": "npm install --no-save leancloud-storage@3 koa@2 koa-bodyparser@4 && env FRAMEWORK=koa KOA_VER=2 mocha test test/koa"
5859
}
5960
}

test/express/https-redirect-test.js

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,10 +28,19 @@ describe('https-redirect', function() {
2828
});
2929
});
3030

31-
it('should not redirect', function(done) {
31+
it('should not redirect (local)', function(done) {
3232
request(app)
3333
.get('/test')
3434
.expect(200)
3535
.expect("Hello World!", done);
3636
});
37+
38+
it('should not redirect (https)', function(done) {
39+
request(app)
40+
.get('/test')
41+
.set('HOST', 'stg-abc.leanapp.cn')
42+
.set('X-Forwarded-Proto', 'https')
43+
.expect(200)
44+
.expect("Hello World!", done);
45+
});
3746
});

test/fixtures/app.js

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,16 @@
11
const AV = require('../..');
22

33
module.exports = function(options) {
4-
if (process.env.FRAMEWORK == 'koa') {
4+
if (process.env.FRAMEWORK === 'koa') {
55
const Koa = require('koa');
66
var app = new Koa();
7-
app.use(AV.koa(options));
7+
8+
if (process.env.KOA_VER === '1') {
9+
app.use(AV.koa(options));
10+
} else {
11+
app.use(AV.koa2(options));
12+
}
13+
814
return app.listen();
915
} else {
1016
return AV.express(options);

test/function-test.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -147,7 +147,7 @@ describe('functions', function() {
147147
__type: 'File',
148148
objectId: '55543fc2e4b0846760bd92f3',
149149
name: 'ttt.jpg',
150-
url: 'http://ac-4h2h4okw.clouddn.com/4qSbLMO866Tf4YtT9QEwJwysTlHGC9sMl7bpTwhQ.jpg'
150+
url: 'http://lc-4h2h4okw.cn-n1.lcfile.com/4qSbLMO866Tf4YtT9QEwJwysTlHGC9sMl7bpTwhQ.jpg'
151151
});
152152

153153
result.avObjects.forEach(function(object) {

test/koa/cookie-session-koa-test.js

Lines changed: 0 additions & 100 deletions
This file was deleted.

test/koa/cookie-session-test.js

Lines changed: 139 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,139 @@
1+
var Koa = require('koa');
2+
var bodyParser = require('koa-bodyparser');
3+
var request = require('supertest');
4+
var should = require('should');
5+
6+
const AV = require('../..');
7+
const appInfo = require('../fixtures/app-info');
8+
9+
var app = new Koa();
10+
11+
if (process.env.KOA_VER === '1') {
12+
app.use(AV.koa());
13+
app.use(bodyParser());
14+
app.use(AV.Cloud.CookieSession({framework: 'koa', secret: 'my secret', maxAge: 3600000, fetchUser: true}));
15+
16+
app.use(function *(next) {
17+
try {
18+
yield next;
19+
} catch (err) {
20+
this.status = err.status || 500;
21+
this.body = err.message;
22+
this.app.emit('error', err, this);
23+
}
24+
});
25+
26+
app.use(function *(next) {
27+
var method = this.request.method;
28+
var url = this.request.url;
29+
30+
if (method === 'GET' && url === '/') {
31+
this.status = 200;
32+
this.body = '<p>Hello world</p>';
33+
} else if (method === 'POST' && url === '/login') {
34+
return AV.User.logIn(this.request.body.username, this.request.body.password).then( user => {
35+
this.saveCurrentUser(user);
36+
this.response.redirect('/profile');
37+
});
38+
} else if (method === 'GET' && url === '/profile') {
39+
this.status = 200;
40+
this.body = this.currentUser;
41+
} else if (method === 'POST' && url === '/logout') {
42+
this.status = 200;
43+
this.saveCurrentUser(null);
44+
} else {
45+
yield next;
46+
}
47+
});
48+
} else {
49+
app.use(AV.koa2());
50+
app.use(bodyParser());
51+
app.use(AV.Cloud.CookieSession({framework: 'koa2', secret: 'my secret', maxAge: 3600000, fetchUser: true}));
52+
53+
app.use(async (ctx, next) => {
54+
try {
55+
await next();
56+
} catch (err) {
57+
ctx.status = err.status || 500;
58+
ctx.body = err.message;
59+
ctx.app.emit('error', err, this);
60+
}
61+
});
62+
63+
app.use(async (ctx, next) => {
64+
var method = ctx.request.method;
65+
var url = ctx.request.url;
66+
67+
if (method === 'GET' && url === '/') {
68+
ctx.status = 200;
69+
ctx.body = '<p>Hello world</p>';
70+
} else if (method === 'POST' && url === '/login') {
71+
return AV.User.logIn(ctx.request.body.username, ctx.request.body.password).then( user => {
72+
ctx.saveCurrentUser(user);
73+
ctx.response.redirect('/profile');
74+
});
75+
} else if (method === 'GET' && url === '/profile') {
76+
ctx.status = 200;
77+
ctx.body = ctx.currentUser;
78+
} else if (method === 'POST' && url === '/logout') {
79+
ctx.status = 200;
80+
ctx.saveCurrentUser(null);
81+
} else {
82+
return next();
83+
}
84+
});
85+
}
86+
87+
var server = app.listen();
88+
89+
describe('koa/cookie-session', function() {
90+
it('index', function(done) {
91+
request(server).get('/')
92+
.expect(200, function(err, res) {
93+
res.headers['content-type'].should.be.startWith('text/html');
94+
res.text.should.be.equal('<p>Hello world</p>');
95+
done(err);
96+
});
97+
});
98+
99+
it('loign', function(done) {
100+
request(server).post('/login')
101+
.send({
102+
username: 'admin',
103+
password: 'admin'
104+
})
105+
.expect(302, function(err, res) {
106+
res.headers.location.should.equal('/profile');
107+
res.headers['set-cookie'][0].indexOf('avos:sess=eyJfdWlkIjoiNTRmZDZhMDNlNGIwNmM0MWUwMGIxZjQwIiwiX3Nlc3Npb25Ub2tlbiI6IncyanJ0a2JlaHAzOG90cW1oYnF1N3liczkifQ==; path=/; expires=').should.equal(0);
108+
res.headers['set-cookie'][1].indexOf('avos:sess.sig=jMYF3Iwhmw903-K1K12MVdAFOh0; path=/; expires=').should.equal(0);
109+
done(err);
110+
});
111+
});
112+
113+
it('profile', function(done) {
114+
request(server).get('/profile')
115+
.set('Cookie', 'avos:sess=eyJfdWlkIjoiNTRmZDZhMDNlNGIwNmM0MWUwMGIxZjQwIiwiX3Nlc3Npb25Ub2tlbiI6IncyanJ0a2JlaHAzOG90cW1oYnF1N3liczkifQ==; avos:sess.sig=jMYF3Iwhmw903-K1K12MVdAFOh0')
116+
.expect(200, function(err, res) {
117+
should.exist(res.body.objectId);
118+
res.body.username.should.be.equal('admin');
119+
done(err);
120+
});
121+
});
122+
123+
it('profile without cookie', function(done) {
124+
request(server).get('/profile')
125+
.expect(204, function(err, res) {
126+
res.body.should.be.empty();
127+
done(err);
128+
});
129+
});
130+
131+
it('logout', function(done) {
132+
request(server).post('/logout')
133+
.set('Cookie', 'avos:sess=eyJfdWlkIjoiNTRmZDZhMDNlNGIwNmM0MWUwMGIxZjQwIiwiX3Nlc3Npb25Ub2tlbiI6IncyanJ0a2JlaHAzOG90cW1oYnF1N3liczkifQ==; avos:sess.sig=jMYF3Iwhmw903-K1K12MVdAFOh0')
134+
.expect(200, function(err, res) {
135+
res.headers['set-cookie'][0].indexOf('avos:sess=; path=/; expires=').should.equal(0);
136+
done(err);
137+
});
138+
})
139+
});

0 commit comments

Comments
 (0)