提交 d9c53e9ced0be1a5892298c1dcdd64935fead4a2

作者 fanwh
1 个父辈 a55f321c

no message

1 1 var path = require('path');
2 2 var serviceDir = path.join(__dirname, '..');
  3 +var maxAge = 24 * 60 * 60 * 1000;
3 4 exports = module.exports = function () {
4 5 return {
5 6 server: {
... ... @@ -16,7 +17,7 @@ exports = module.exports = function () {
16 17 options: {}
17 18 },
18 19 staticServer: {
19   - maxAge: 24 * 60 * 60 * 1000
  20 + maxAge: maxAge
20 21 }
21 22 },
22 23 logger: {
... ... @@ -24,6 +25,35 @@ exports = module.exports = function () {
24 25 },
25 26 output: {
26 27
  28 + },
  29 + cookieParser: 'igloo-change-me',
  30 + session: {
  31 + secret: 'igloo-change-me',
  32 + key: 'igloo',
  33 + cookie: {
  34 + path: '/',
  35 + httpOnly: true,
  36 + secure: false,
  37 + sameSite: 'strict',
  38 + maxAge: maxAge
  39 + },
  40 + resave: true,
  41 + saveUninitialized: true
  42 + },
  43 + notApiRouteRegexp: /^(?!\/__webpack_hmr\/)|(?!\/*.ico).*$/,
  44 + redis: {
  45 + prefix: 'igloo-development',
  46 + host: '127.0.0.1',
  47 + port: 6379,
  48 + pass: ''
  49 + },
  50 + proxy: {
  51 + target: 'http://47.110.158.110:20000',
  52 + apiRouteRegexp: '/api',
  53 + authUrl: '/uaa/v1/auth/tokens',
  54 + refreshUrl: '/uaa/v1/auth/tokens',
  55 + signOutUrl: '/signOut',
  56 + signInUrl: '/#login',
27 57 }
28 58 };
29 59 };
... ...
... ... @@ -42,14 +42,10 @@ exports = module.exports = function (logger, settings) {
42 42 // app.use(winstonRequestLogger.create(logger));
43 43 // }
44 44
  45 + // parse
  46 + app.use(bodyParser.urlencoded({ limit: '10mb', extended: true }));
45 47 // parse request bodies
46   - app.use(
47   - bodyParser.json({ limit: '10mb' }),
48   - bodyParser.urlencoded({
49   - limit: '10mb',
50   - extended: true
51   - })
52   - );
  48 + app.use(bodyParser.json({ limit: '10mb' }));
53 49 };
54 50
55 51 exports['@require'] = ['igloo/logger', 'igloo/settings'];
... ...
  1 +
  2 +// # sessions
  3 +var session = require('express-session');
  4 +var cookieParser = require('cookie-parser');
  5 +
  6 +exports = module.exports = function (settings, sessions) {
  7 +
  8 + var app = this;
  9 + // pass a secret to cookieParser() for signed cookies
  10 + app.all(settings.notApiRouteRegexp, cookieParser(settings.cookieParser));
  11 +
  12 + // add req.session cookie support
  13 + settings.session.store = sessions;
  14 + app.all(settings.notApiRouteRegexp, session(settings.session));
  15 +
  16 + // add flash message support
  17 + app.use(session(settings.session));
  18 +};
  19 +
  20 +exports['@require'] = ['igloo/settings', 'igloo/sessions'];
... ...
  1 +//代理RESTful API
  2 +var express = require('express');
  3 +exports = module.exports = function (settings, proxy) {
  4 +
  5 + var app = this;
  6 + var router = express.Router();
  7 + if (settings.proxy) {
  8 + app.use(settings.proxy.apiRouteRegexp, router);
  9 + router.all('*', function (req, res, next) {
  10 + proxy.web(req, res, next);
  11 + });
  12 + }
  13 +};
  14 +
  15 +exports['@require'] = ['igloo/settings', 'igloo/restler'];
... ...
  1 +//RESTful API client 代理
  2 +
  3 +var rest = require('restler');
  4 +var URL = require('url');
  5 +exports = module.exports = function (logger, settings) {
  6 +
  7 + var client = {};
  8 +
  9 + function targetUrl(originUrl) {
  10 + if (settings.proxy && settings.proxy.target && settings.proxy.apiRouteRegexp) {
  11 + return settings.proxy.target + originUrl.substring(settings.proxy.apiRouteRegexp.length);
  12 + } else {
  13 + logger.error('config miss proxy target');
  14 + }
  15 + }
  16 +
  17 + function getTokens(req) {
  18 + console.log("##@#@", req.session);
  19 + if (req.session.token) {
  20 + var token = {};
  21 + try {
  22 + token = JSON.parse(req.session.token);
  23 + } catch (error) {
  24 + logger.error("token 字符串不能被解析", error);
  25 + }
  26 + return token;
  27 + } else {
  28 + logger.error("401 token不存在");
  29 + }
  30 + }
  31 +
  32 + function refreshToken(req, res, next, reqOption) {
  33 + var token = getTokens(req);
  34 + var params = {
  35 + 'grant_type': 'refresh_token',
  36 + 'refresh_token': token.refresh_token
  37 + };
  38 + if (token.tenant && token.tenant.tenant_id) {
  39 + params['account'] = token.tenant.tenant_id;
  40 + }
  41 + var options = {
  42 + method: 'post',
  43 + data: JSON.stringify(params || {}),
  44 + headers: { 'Content-Type': 'application/json', 'Accept': 'application/json' },
  45 + timeout: 60 * 1000
  46 + }
  47 + var refreshUrl = settings.proxy.target + settings.proxy.refreshUrl;
  48 + rest.request(refreshUrl, options)
  49 + .on('success', function (data, response) {
  50 + req.session.token = data;
  51 + req.session.save(function (err) {
  52 + if (err)
  53 + logger.error(err);
  54 + else
  55 + requestAction(reqOption.url, req, res, next)
  56 + })
  57 + })
  58 + .on('fail', function (data, response) {
  59 + logger.error(data);
  60 + res.send({ 'message': '刷新token失败,请重新登陆' });
  61 + })
  62 + .on('error', function (err, response) {
  63 + logger.error(err);
  64 + res.send(err);
  65 + })
  66 + .on('timeout', function (ms) {
  67 + logger.error('timeout', ms);
  68 + res.send({ 'message': '请求超时' });
  69 + });
  70 + }
  71 +
  72 + function handleSuccess(data, response, req, res, next, reqOption) {
  73 + if (reqOption.url.indexOf(settings.proxy.authUrl) != -1) {
  74 + req.session.token = data;
  75 + req.session.save(function (err) {
  76 + if (err)
  77 + logger.error(err);
  78 + else
  79 + res.send(data);
  80 + })
  81 + } else {
  82 + res.send(data);
  83 + }
  84 + }
  85 +
  86 + function handleFail(data, response, req, res, next, reqOption) {
  87 + if (response.statusCode === 401) {
  88 + refreshToken(req, res, next, reqOption);
  89 + } else {
  90 + res.send(data);
  91 + }
  92 + }
  93 +
  94 + function getOptions(req) {
  95 + var options = {
  96 + method: req.method.toLowerCase(),
  97 + query: req.query,
  98 + data: JSON.stringify(req.body || {}),
  99 + headers: { 'Content-Type': 'application/json', 'Accept': 'application/json' },
  100 + timeout: 60 * 1000
  101 + }
  102 + if (req.session.token) {
  103 + var token = getTokens(req);
  104 + options['accessToken'] = token.access_token
  105 + }
  106 + return options;
  107 + }
  108 +
  109 + function requestAction(url, req, res, next) {
  110 + var options = getOptions(req);
  111 + logger.info('options', options);
  112 + rest.request(url, options)
  113 + .on('success', function (data, response) {
  114 + handleSuccess(data, response, req, res, next, { url, options });
  115 + })
  116 + .on('fail', function (data, response) {
  117 + handleFail(data, response, req, res, next, { url, options });
  118 + })
  119 + .on('error', function (err, response) {
  120 + logger.error(err);
  121 + res.send(err);
  122 + })
  123 + .on('timeout', function (ms) {
  124 + logger.error('timeout', ms);
  125 + res.send({ 'message': '请求超时' });
  126 + });
  127 + }
  128 +
  129 + client.web = function (req, res, next) {
  130 + var target = targetUrl(req.originalUrl);
  131 + requestAction(target, req, res, next);
  132 + }
  133 +
  134 +
  135 + return client;
  136 +};
  137 +
  138 +
  139 +exports['@singleton'] = true;
  140 +exports['@require'] = ['igloo/logger', 'igloo/settings'];
\ No newline at end of file
... ...
... ... @@ -21,9 +21,10 @@
21 21 "express-session": "^1.16.1",
22 22 "lodash": "^4.17.11",
23 23 "morgan": "~1.6.1",
  24 + "restler": "^3.4.0",
24 25 "serve-favicon": "~2.3.0",
25 26 "serve-static": "^1.13.2",
26 27 "underscore": "^1.9.1",
27 28 "winston": "^3.2.1"
28 29 }
29   -}
\ No newline at end of file
  30 +}
... ...
1 1 var express = require('express');
2 2 var IoC = require('electrolyte');
3 3
4   -exports = module.exports = function (settings) {
  4 +exports = module.exports = function (settings, logger) {
5 5 var app = this;
6   - var router = express.Router();
7   - var controller = {
8   - get: function () {
9   -
10   - }, post: function () {
11   -
12   - }, put: function () {
13   -
14   - }, patch: function () {
15   -
16   - }, head: function () {
17   -
18   - }, patch: function () {
19   -
20   - }, delete: function () {
21   -
22   - }
23   - };
24   -
25   - router.get(
26   - '/*',
27   - controller.get
28   - );
29   -
30   - router.post(
31   - '/*',
32   - controller.post
33   - );
34   -
35   - router.put(
36   - '/*',
37   - controller.put
38   - );
39   -
40   - router.patch(
41   - '/*',
42   - controller.patch
43   - );
44   -
45   - router.head(
46   - '/*',
47   - controller.head
48   - );
49   -
50   - router.delete(
51   - '/*',
52   - controller.delete
53   - );
54   -
55   - app.use('/api', router);
56 6 app.use('/', function (req, res, next) {
57 7 res.render('index', { 'csrfToken': 'xxxx' });
58 8 next();
59 9 });
  10 +
  11 + app.use(settings.proxy.signOutUrl, function (req, res, next) {
  12 + req.session.token = null;
  13 + req.session.save(function (err) {
  14 + if (err)
  15 + logger.error(err);
  16 + else
  17 + res.redirect(settings.proxy.signInUrl);
  18 + });
  19 + });
  20 +
60 21 };
61 22
62 23 exports['@singleton'] = true;
63   -exports['@require'] = ['igloo/settings'];
  24 +exports['@require'] = ['igloo/settings', 'igloo/logger'];
... ...
... ... @@ -418,6 +418,10 @@ http-errors@~1.6.2:
418 418 setprototypeof "1.1.0"
419 419 statuses ">= 1.4.0 < 2"
420 420
  421 +iconv-lite@0.2.11:
  422 + version "0.2.11"
  423 + resolved "https://registry.npm.taobao.org/iconv-lite/download/iconv-lite-0.2.11.tgz#1ce60a3a57864a292d1321ff4609ca4bb965adc8"
  424 +
421 425 iconv-lite@0.4.24:
422 426 version "0.4.24"
423 427 resolved "https://registry.npm.taobao.org/iconv-lite/download/iconv-lite-0.4.24.tgz#2022b4b25fbddc21d2f524974a474aafe733908b"
... ... @@ -602,6 +606,10 @@ proxy-addr@~1.0.10:
602 606 forwarded "~0.1.0"
603 607 ipaddr.js "1.0.5"
604 608
  609 +qs@1.2.0:
  610 + version "1.2.0"
  611 + resolved "https://registry.npm.taobao.org/qs/download/qs-1.2.0.tgz#ed079be28682147e6fd9a34cc2b0c1e0ec6453ee"
  612 +
605 613 qs@4.0.0:
606 614 version "4.0.0"
607 615 resolved "http://registry.npm.taobao.org/qs/download/qs-4.0.0.tgz#c31d9b74ec27df75e543a86c78728ed8d4623607"
... ... @@ -667,6 +675,15 @@ redis@^2.8.0:
667 675 redis-commands "^1.2.0"
668 676 redis-parser "^2.6.0"
669 677
  678 +restler@^3.4.0:
  679 + version "3.4.0"
  680 + resolved "https://registry.npm.taobao.org/restler/download/restler-3.4.0.tgz#741ec0b3d16b949feea2813d0c3c68529e888d9b"
  681 + dependencies:
  682 + iconv-lite "0.2.11"
  683 + qs "1.2.0"
  684 + xml2js "0.4.0"
  685 + yaml "0.2.3"
  686 +
670 687 safe-buffer@5.1.2, safe-buffer@~5.1.0, safe-buffer@~5.1.1:
671 688 version "5.1.2"
672 689 resolved "http://registry.npm.taobao.org/safe-buffer/download/safe-buffer-5.1.2.tgz#991ec69d296e0313747d59bdfd2b745c35f8828d"
... ... @@ -675,6 +692,10 @@ safe-buffer@5.1.2, safe-buffer@~5.1.0, safe-buffer@~5.1.1:
675 692 version "2.1.2"
676 693 resolved "https://registry.npm.taobao.org/safer-buffer/download/safer-buffer-2.1.2.tgz#44fa161b0187b9549dd84bb91802f9bd8385cd6a"
677 694
  695 +sax@0.5.x:
  696 + version "0.5.8"
  697 + resolved "https://registry.npm.taobao.org/sax/download/sax-0.5.8.tgz#d472db228eb331c2506b0e8c15524adb939d12c1"
  698 +
678 699 scripts@0.1.x:
679 700 version "0.1.0"
680 701 resolved "http://registry.npm.taobao.org/scripts/download/scripts-0.1.0.tgz#3eb19713b5ad1f58bc3e39ce63606d6beaa00693"
... ... @@ -885,3 +906,18 @@ winston@^3.2.1:
885 906 stack-trace "0.0.x"
886 907 triple-beam "^1.3.0"
887 908 winston-transport "^4.3.0"
  909 +
  910 +xml2js@0.4.0:
  911 + version "0.4.0"
  912 + resolved "https://registry.npm.taobao.org/xml2js/download/xml2js-0.4.0.tgz#124fc4114b4129c810800ecb2ac86cf25462cb9a"
  913 + dependencies:
  914 + sax "0.5.x"
  915 + xmlbuilder ">=0.4.2"
  916 +
  917 +xmlbuilder@>=0.4.2:
  918 + version "12.0.1"
  919 + resolved "https://registry.npm.taobao.org/xmlbuilder/download/xmlbuilder-12.0.1.tgz#885f0ab731e0c9bfd4970381513760131cc71a25"
  920 +
  921 +yaml@0.2.3:
  922 + version "0.2.3"
  923 + resolved "https://registry.npm.taobao.org/yaml/download/yaml-0.2.3.tgz#b5450e92e76ef36b5dd24e3660091ebaeef3e5c7"
... ...
注册登录 后发表评论