Mukho

Add IP address in log

...@@ -122,6 +122,7 @@ io.sockets.on('connection', function(socket) { ...@@ -122,6 +122,7 @@ io.sockets.on('connection', function(socket) {
122 }) 122 })
123 }) 123 })
124 124
125 -server.listen(PORT, function(){ 125 +// 서버 가동(IPv4 형식으로 express 설정)
126 +server.listen(PORT, '127.0.0.1', function(){
126 console.log(logString+"서버가 시작되었습니다.(Port: "+PORT+")"); 127 console.log(logString+"서버가 시작되었습니다.(Port: "+PORT+")");
127 }); 128 });
...\ No newline at end of file ...\ No newline at end of file
......
1 +The MIT License (MIT)
2 +
3 +Copyright (c) 2014-2016 Aras Atasaygin
4 +
5 +Permission is hereby granted, free of charge, to any person obtaining a copy
6 +of this software and associated documentation files (the "Software"), to deal
7 +in the Software without restriction, including without limitation the rights
8 +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 +copies of the Software, and to permit persons to whom the Software is
10 +furnished to do so, subject to the following conditions:
11 +
12 +The above copyright notice and this permission notice shall be included in all
13 +copies or substantial portions of the Software.
14 +
15 +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 +SOFTWARE.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
1 +{
2 + "_from": "is_js@^0.9.0",
3 + "_id": "is_js@0.9.0",
4 + "_inBundle": false,
5 + "_integrity": "sha1-CrlFQFArp6+iTIVqqYVWFmnpxS0=",
6 + "_location": "/is_js",
7 + "_phantomChildren": {},
8 + "_requested": {
9 + "type": "range",
10 + "registry": true,
11 + "raw": "is_js@^0.9.0",
12 + "name": "is_js",
13 + "escapedName": "is_js",
14 + "rawSpec": "^0.9.0",
15 + "saveSpec": null,
16 + "fetchSpec": "^0.9.0"
17 + },
18 + "_requiredBy": [
19 + "/request-ip"
20 + ],
21 + "_resolved": "https://registry.npmjs.org/is_js/-/is_js-0.9.0.tgz",
22 + "_shasum": "0ab94540502ba7afa24c856aa985561669e9c52d",
23 + "_spec": "is_js@^0.9.0",
24 + "_where": "C:\\Users\\KoMoGoon\\Desktop\\oss_project\\Singer-Composer\\node_modules\\request-ip",
25 + "bugs": {
26 + "url": "https://github.com/arasatasaygin/is.js/issues"
27 + },
28 + "bundleDependencies": false,
29 + "deprecated": false,
30 + "description": "micro check library",
31 + "devDependencies": {
32 + "chai": "^3.4.0",
33 + "eslint": "^2.13.1",
34 + "lodash": "^4.15.0",
35 + "mocha": "^2.2.1",
36 + "mocha-phantomjs": "^4.1.0",
37 + "pre-commit": "^1.1.3",
38 + "uglify-js": "^2.7.3"
39 + },
40 + "files": [
41 + "is.js",
42 + "is.min.js"
43 + ],
44 + "homepage": "http://is.js.org/",
45 + "license": "MIT",
46 + "main": "is.js",
47 + "name": "is_js",
48 + "pre-commit": [
49 + "lint"
50 + ],
51 + "repository": {
52 + "type": "git",
53 + "url": "git+https://github.com/arasatasaygin/is.js.git"
54 + },
55 + "scripts": {
56 + "build": "npm run lint && npm run min",
57 + "lint": "eslint .",
58 + "min": "uglifyjs is.js -m --comments \"/^!/\" -o is.min.js",
59 + "test": "mocha --check-leaks -R dot",
60 + "test:phantom": "mocha-phantomjs -R dot test/index.html"
61 + },
62 + "version": "0.9.0"
63 +}
1 +# Change Log
2 +
3 +## [2.1.2](https://github.com/pbojinov/request-ip/tree/2.1.2) (2018-10-29)
4 +[Full Changelog](https://github.com/pbojinov/request-ip/compare/2.1.1...2.1.2)
5 +
6 +**Closed issues:**
7 +
8 +- Handle Firebase hosting header fastly-client-ip [\#37](https://github.com/pbojinov/request-ip/issues/37)
9 +
10 +**Merged pull requests:**
11 +
12 +- chore: improve packaging [\#40](https://github.com/pbojinov/request-ip/pull/40) ([pi0](https://github.com/pi0))
13 +- fixed Cannot redefine property: clientIp error [\#39](https://github.com/pbojinov/request-ip/pull/39) ([karankohli13](https://github.com/karankohli13))
14 +- Add firebase hosting header [\#38](https://github.com/pbojinov/request-ip/pull/38) ([vishalvijay](https://github.com/vishalvijay))
15 +
16 +## [2.1.1](https://github.com/pbojinov/request-ip/tree/2.1.1) (2018-07-03)
17 +[Full Changelog](https://github.com/pbojinov/request-ip/compare/2.1.0...2.1.1)
18 +
19 +## [2.1.0](https://github.com/pbojinov/request-ip/tree/2.1.0) (2018-07-03)
20 +[Full Changelog](https://github.com/pbojinov/request-ip/compare/2.0.2...2.1.0)
21 +
22 +**Closed issues:**
23 +
24 +- Not getting the right ip first time [\#28](https://github.com/pbojinov/request-ip/issues/28)
25 +- Allow using node \> 6 [\#27](https://github.com/pbojinov/request-ip/issues/27)
26 +
27 +**Merged pull requests:**
28 +
29 +- Get client ip when using AWS Api Gateway + Lambda. [\#35](https://github.com/pbojinov/request-ip/pull/35) ([rafaelthemendes](https://github.com/rafaelthemendes))
30 +- redefine attribute getter [\#34](https://github.com/pbojinov/request-ip/pull/34) ([isayme](https://github.com/isayme))
31 +
32 +## [2.0.2](https://github.com/pbojinov/request-ip/tree/2.0.2) (2017-06-26)
33 +[Full Changelog](https://github.com/pbojinov/request-ip/compare/2.0.1...2.0.2)
34 +
35 +**Closed issues:**
36 +
37 +- azure web app adds port to x-forwarded-for [\#29](https://github.com/pbojinov/request-ip/issues/29)
38 +
39 +**Merged pull requests:**
40 +
41 +- handling x-forwarded-for with ip:port [\#30](https://github.com/pbojinov/request-ip/pull/30) ([luisrudge](https://github.com/luisrudge))
42 +
43 +## [2.0.1](https://github.com/pbojinov/request-ip/tree/2.0.1) (2017-03-09)
44 +[Full Changelog](https://github.com/pbojinov/request-ip/compare/2.0.0...2.0.1)
45 +
46 +**Implemented enhancements:**
47 +
48 +- ES2015 Support [\#22](https://github.com/pbojinov/request-ip/issues/22)
49 +
50 +## [2.0.0](https://github.com/pbojinov/request-ip/tree/2.0.0) (2017-03-07)
51 +[Full Changelog](https://github.com/pbojinov/request-ip/compare/1.3.0...2.0.0)
52 +
53 +**Closed issues:**
54 +
55 +- optimized your code a bit \(no need to evalutate every option before choosing first one that matches. just evaluate then return on first match\) [\#15](https://github.com/pbojinov/request-ip/issues/15)
56 +
57 +**Merged pull requests:**
58 +
59 +- Refactor to ES6 [\#23](https://github.com/pbojinov/request-ip/pull/23) ([fluxsauce](https://github.com/fluxsauce))
60 +
61 +## [1.3.0](https://github.com/pbojinov/request-ip/tree/1.3.0) (2017-03-03)
62 +[Full Changelog](https://github.com/pbojinov/request-ip/compare/1.2.3...1.3.0)
63 +
64 +**Closed issues:**
65 +
66 +- Support Cloudflare? [\#20](https://github.com/pbojinov/request-ip/issues/20)
67 +- How to receive IP in client [\#17](https://github.com/pbojinov/request-ip/issues/17)
68 +
69 +**Merged pull requests:**
70 +
71 +- Adding support for CF-Connecting-IP and True-Client-IP [\#21](https://github.com/pbojinov/request-ip/pull/21) ([fluxsauce](https://github.com/fluxsauce))
72 +- Return once we find something and don't crash if req.headers is undefined [\#19](https://github.com/pbojinov/request-ip/pull/19) ([rokob](https://github.com/rokob))
73 +- Ignore 'unknown' ip addresses in X-Forwarded-For header [\#18](https://github.com/pbojinov/request-ip/pull/18) ([raunc](https://github.com/raunc))
74 +
75 +## [1.2.3](https://github.com/pbojinov/request-ip/tree/1.2.3) (2016-11-02)
76 +[Full Changelog](https://github.com/pbojinov/request-ip/compare/1.2.2...1.2.3)
77 +
78 +**Closed issues:**
79 +
80 +- Are there any security concerns when saving the IP directly to a database? [\#16](https://github.com/pbojinov/request-ip/issues/16)
81 +- I'm not getting local host ip address 127.0.0.1 [\#14](https://github.com/pbojinov/request-ip/issues/14)
82 +
83 +## [1.2.2](https://github.com/pbojinov/request-ip/tree/1.2.2) (2016-01-27)
84 +[Full Changelog](https://github.com/pbojinov/request-ip/compare/1.2.1...1.2.2)
85 +
86 +## [1.2.1](https://github.com/pbojinov/request-ip/tree/1.2.1) (2016-01-27)
87 +[Full Changelog](https://github.com/pbojinov/request-ip/compare/1.2.0...1.2.1)
88 +
89 +**Merged pull requests:**
90 +
91 +- introduce a built-in default implementation for a connect-middleware [\#12](https://github.com/pbojinov/request-ip/pull/12) ([osherx](https://github.com/osherx))
92 +
93 +## [1.2.0](https://github.com/pbojinov/request-ip/tree/1.2.0) (2016-01-27)
94 +[Full Changelog](https://github.com/pbojinov/request-ip/compare/1.1.4...1.2.0)
95 +
96 +**Merged pull requests:**
97 +
98 +- Cleanup [\#13](https://github.com/pbojinov/request-ip/pull/13) ([minecrawler](https://github.com/minecrawler))
99 +- Got it working in a case that was returning null [\#11](https://github.com/pbojinov/request-ip/pull/11) ([andfaulkner](https://github.com/andfaulkner))
100 +
101 +## [1.1.4](https://github.com/pbojinov/request-ip/tree/1.1.4) (2015-07-23)
102 +[Full Changelog](https://github.com/pbojinov/request-ip/compare/1.1.3...1.1.4)
103 +
104 +**Merged pull requests:**
105 +
106 +- Add case management where you can not find the IP address [\#10](https://github.com/pbojinov/request-ip/pull/10) ([sitexw](https://github.com/sitexw))
107 +
108 +## [1.1.3](https://github.com/pbojinov/request-ip/tree/1.1.3) (2015-04-20)
109 +[Full Changelog](https://github.com/pbojinov/request-ip/compare/1.1.2...1.1.3)
110 +
111 +## [1.1.2](https://github.com/pbojinov/request-ip/tree/1.1.2) (2015-04-04)
112 +[Full Changelog](https://github.com/pbojinov/request-ip/compare/1.1.1...1.1.2)
113 +
114 +## [1.1.1](https://github.com/pbojinov/request-ip/tree/1.1.1) (2015-04-04)
115 +[Full Changelog](https://github.com/pbojinov/request-ip/compare/1.1.0...1.1.1)
116 +
117 +**Closed issues:**
118 +
119 +- needs semver [\#7](https://github.com/pbojinov/request-ip/issues/7)
120 +
121 +## [1.1.0](https://github.com/pbojinov/request-ip/tree/1.1.0) (2015-04-04)
122 +[Full Changelog](https://github.com/pbojinov/request-ip/compare/v0.0.4...1.1.0)
123 +
124 +**Merged pull requests:**
125 +
126 +- Update README.md [\#9](https://github.com/pbojinov/request-ip/pull/9) ([coolaj86](https://github.com/coolaj86))
127 +- This deserves a production version number. [\#8](https://github.com/pbojinov/request-ip/pull/8) ([coolaj86](https://github.com/coolaj86))
128 +
129 +## [v0.0.4](https://github.com/pbojinov/request-ip/tree/v0.0.4) (2015-01-16)
130 +**Closed issues:**
131 +
132 +- Invalid header [\#5](https://github.com/pbojinov/request-ip/issues/5)
133 +- replace req.header\('X-Forwarded-For'\) for req.header\('X-Forwarder-For'\)\); [\#3](https://github.com/pbojinov/request-ip/issues/3)
134 +- Nginx problems [\#2](https://github.com/pbojinov/request-ip/issues/2)
135 +
136 +**Merged pull requests:**
137 +
138 +- Add support for X-Real-IP Header [\#6](https://github.com/pbojinov/request-ip/pull/6) ([pmarques](https://github.com/pmarques))
139 +- fix bug X-Forwarder-For [\#4](https://github.com/pbojinov/request-ip/pull/4) ([morello-cl](https://github.com/morello-cl))
140 +- Add a Bitdeli Badge to README [\#1](https://github.com/pbojinov/request-ip/pull/1) ([bitdeli-chef](https://github.com/bitdeli-chef))
141 +
142 +
143 +
144 +\* *This Change Log was automatically generated by [github_changelog_generator](https://github.com/skywinder/Github-Changelog-Generator)*
...\ No newline at end of file ...\ No newline at end of file
1 +The MIT License (MIT)
2 +
3 +Copyright (c) 2018 Petar Bojinov - petarbojinov@gmail.com
4 +
5 +Permission is hereby granted, free of charge, to any person obtaining a copy of
6 +this software and associated documentation files (the "Software"), to deal in
7 +the Software without restriction, including without limitation the rights to
8 +use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
9 +the Software, and to permit persons to whom the Software is furnished to do so,
10 +subject to the following conditions:
11 +
12 +The above copyright notice and this permission notice shall be included in all
13 +copies or substantial portions of the Software.
14 +
15 +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
17 +FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
18 +COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
19 +IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
20 +CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
1 +# request-ip
2 +
3 +A tiny Node.js module for retrieving a request's IP address.
4 +
5 +![](https://nodei.co/npm/request-ip.png?downloads=true&cacheBust=2)
6 +
7 +![](https://travis-ci.org/pbojinov/request-ip.svg?branch=master)
8 +[![Coverage Status](https://coveralls.io/repos/pbojinov/request-ip/badge.svg)](https://coveralls.io/r/pbojinov/request-ip)
9 +![](https://img.shields.io/npm/l/express.svg)
10 +[![npm version](https://badge.fury.io/js/request-ip.svg)](https://badge.fury.io/js/request-ip)
11 +
12 +## Installation
13 +
14 +```bash
15 +npm install request-ip --save
16 +```
17 +
18 +## Getting Started
19 +
20 +```javascript
21 +const requestIp = require('request-ip');
22 +
23 +// inside middleware handler
24 +const ipMiddleware = function(req, res, next) {
25 + const clientIp = requestIp.getClientIp(req);
26 + next();
27 +};
28 +
29 +// on localhost you'll see 127.0.0.1 if you're using IPv4
30 +// or ::1, ::ffff:127.0.0.1 if you're using IPv6
31 +```
32 +
33 +### As Connect Middleware
34 +
35 +```javascript
36 +const requestIp = require('request-ip');
37 +app.use(requestIp.mw())
38 +
39 +app.use(function(req, res) {
40 + const ip = req.clientIp;
41 + res.end(ip);
42 +});
43 +```
44 +
45 +To see a full working code for the middleware, check out the [examples](https://github.com/pbojinov/request-ip/tree/master/examples) folder.
46 +
47 +The connect-middleware also supports retrieving the ip address under a custom attribute name, which also works as a container for any future settings.
48 +
49 +## How It Works
50 +
51 +It looks for specific headers in the request and falls back to some defaults if they do not exist.
52 +
53 +The user ip is determined by the following order:
54 +
55 +1. `X-Client-IP`
56 +2. `X-Forwarded-For` (Header may return multiple IP addresses in the format: "client IP, proxy 1 IP, proxy 2 IP", so we take the the first one.)
57 +3. `CF-Connecting-IP` (Cloudflare)
58 +4. `Fastly-Client-Ip` (Fastly CDN and Firebase hosting header when forwared to a cloud function)
59 +5. `True-Client-Ip` (Akamai and Cloudflare)
60 +6. `X-Real-IP` (Nginx proxy/FastCGI)
61 +7. `X-Cluster-Client-IP` (Rackspace LB, Riverbed Stingray)
62 +8. `X-Forwarded`, `Forwarded-For` and `Forwarded` (Variations of #2)
63 +9. `req.connection.remoteAddress`
64 +10. `req.socket.remoteAddress`
65 +11. `req.connection.socket.remoteAddress`
66 +12. `req.info.remoteAddress`
67 +
68 +If an IP address cannot be found, it will return `null`.
69 +
70 +## Samples Use Cases
71 +
72 +* Getting a user's IP for geolocation.
73 +
74 +
75 +## Running the Tests
76 +
77 +Make sure you have the necessary dev dependencies needed to run the tests:
78 +
79 +```
80 +npm install
81 +```
82 +
83 +Run the integration tests
84 +
85 +```
86 +npm test
87 +```
88 +
89 +## Release Notes
90 +
91 +See the wonderful [changelog](https://github.com/pbojinov/request-ip/blob/master/CHANGELOG.md)
92 +
93 +To easily generate a new changelog, install [github-changelog-generator](https://github.com/skywinder/github-changelog-generator) then run `npm run changelog`.
94 +
95 +## Contributors
96 +
97 +* Thanks to [@osherx](https://github.com/osherx) for adding the connect-middleware.
98 +* Thanks to [@raunc](https://github.com/raunc) for adding Squid proxy support.
99 +* Thanks to [@fluxsauce](https://github.com/fluxsauce) for adding `CF-Connecting-IP`, `True-Client-IP`, and ES6 support.
100 +* Thanks to [@vishalvijay](https://github.com/vishalvijay) for adding Fastly/Firebase hosting support.
101 +
102 +## License
103 +
104 +The MIT License (MIT) - 2018
No preview for this file type
1 +"use strict";
2 +
3 +function _typeof(obj) { if (typeof Symbol === "function" && typeof Symbol.iterator === "symbol") { _typeof = function _typeof(obj) { return typeof obj; }; } else { _typeof = function _typeof(obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }; } return _typeof(obj); }
4 +
5 +var is = require('is_js');
6 +/**
7 + * Parse x-forwarded-for headers.
8 + *
9 + * @param {string} value - The value to be parsed.
10 + * @return {string|null} First known IP address, if any.
11 + */
12 +
13 +
14 +function getClientIpFromXForwardedFor(value) {
15 + if (!is.existy(value)) {
16 + return null;
17 + }
18 +
19 + if (is.not.string(value)) {
20 + throw new TypeError("Expected a string, got \"".concat(_typeof(value), "\""));
21 + } // x-forwarded-for may return multiple IP addresses in the format:
22 + // "client IP, proxy 1 IP, proxy 2 IP"
23 + // Therefore, the right-most IP address is the IP address of the most recent proxy
24 + // and the left-most IP address is the IP address of the originating client.
25 + // source: http://docs.aws.amazon.com/elasticloadbalancing/latest/classic/x-forwarded-headers.html
26 + // Azure Web App's also adds a port for some reason, so we'll only use the first part (the IP)
27 +
28 +
29 + var forwardedIps = value.split(',').map(function (e) {
30 + var ip = e.trim();
31 +
32 + if (ip.includes(':')) {
33 + var splitted = ip.split(':'); // make sure we only use this if it's ipv4 (ip:port)
34 +
35 + if (splitted.length === 2) {
36 + return splitted[0];
37 + }
38 + }
39 +
40 + return ip;
41 + }); // Sometimes IP addresses in this header can be 'unknown' (http://stackoverflow.com/a/11285650).
42 + // Therefore taking the left-most IP address that is not unknown
43 + // A Squid configuration directive can also set the value to "unknown" (http://www.squid-cache.org/Doc/config/forwarded_for/)
44 +
45 + return forwardedIps.find(is.ip);
46 +}
47 +/**
48 + * Determine client IP address.
49 + *
50 + * @param req
51 + * @returns {string} ip - The IP address if known, defaulting to empty string if unknown.
52 + */
53 +
54 +
55 +function getClientIp(req) {
56 + // Server is probably behind a proxy.
57 + if (req.headers) {
58 + // Standard headers used by Amazon EC2, Heroku, and others.
59 + if (is.ip(req.headers['x-client-ip'])) {
60 + return req.headers['x-client-ip'];
61 + } // Load-balancers (AWS ELB) or proxies.
62 +
63 +
64 + var xForwardedFor = getClientIpFromXForwardedFor(req.headers['x-forwarded-for']);
65 +
66 + if (is.ip(xForwardedFor)) {
67 + return xForwardedFor;
68 + } // Cloudflare.
69 + // @see https://support.cloudflare.com/hc/en-us/articles/200170986-How-does-Cloudflare-handle-HTTP-Request-headers-
70 + // CF-Connecting-IP - applied to every request to the origin.
71 +
72 +
73 + if (is.ip(req.headers['cf-connecting-ip'])) {
74 + return req.headers['cf-connecting-ip'];
75 + } // Fastly and Firebase hosting header (When forwared to cloud function)
76 +
77 +
78 + if (is.ip(req.headers['fastly-client-ip'])) {
79 + return req.headers['fastly-client-ip'];
80 + } // Akamai and Cloudflare: True-Client-IP.
81 +
82 +
83 + if (is.ip(req.headers['true-client-ip'])) {
84 + return req.headers['true-client-ip'];
85 + } // Default nginx proxy/fcgi; alternative to x-forwarded-for, used by some proxies.
86 +
87 +
88 + if (is.ip(req.headers['x-real-ip'])) {
89 + return req.headers['x-real-ip'];
90 + } // (Rackspace LB and Riverbed's Stingray)
91 + // http://www.rackspace.com/knowledge_center/article/controlling-access-to-linux-cloud-sites-based-on-the-client-ip-address
92 + // https://splash.riverbed.com/docs/DOC-1926
93 +
94 +
95 + if (is.ip(req.headers['x-cluster-client-ip'])) {
96 + return req.headers['x-cluster-client-ip'];
97 + }
98 +
99 + if (is.ip(req.headers['x-forwarded'])) {
100 + return req.headers['x-forwarded'];
101 + }
102 +
103 + if (is.ip(req.headers['forwarded-for'])) {
104 + return req.headers['forwarded-for'];
105 + }
106 +
107 + if (is.ip(req.headers.forwarded)) {
108 + return req.headers.forwarded;
109 + }
110 + } // Remote address checks.
111 +
112 +
113 + if (is.existy(req.connection)) {
114 + if (is.ip(req.connection.remoteAddress)) {
115 + return req.connection.remoteAddress;
116 + }
117 +
118 + if (is.existy(req.connection.socket) && is.ip(req.connection.socket.remoteAddress)) {
119 + return req.connection.socket.remoteAddress;
120 + }
121 + }
122 +
123 + if (is.existy(req.socket) && is.ip(req.socket.remoteAddress)) {
124 + return req.socket.remoteAddress;
125 + }
126 +
127 + if (is.existy(req.info) && is.ip(req.info.remoteAddress)) {
128 + return req.info.remoteAddress;
129 + } // AWS Api Gateway + Lambda
130 +
131 +
132 + if (is.existy(req.requestContext) && is.existy(req.requestContext.identity) && is.ip(req.requestContext.identity.sourceIp)) {
133 + return req.requestContext.identity.sourceIp;
134 + }
135 +
136 + return null;
137 +}
138 +/**
139 + * Expose request IP as a middleware.
140 + *
141 + * @param {object} [options] - Configuration.
142 + * @param {string} [options.attributeName] - Name of attribute to augment request object with.
143 + * @return {*}
144 + */
145 +
146 +
147 +function mw(options) {
148 + // Defaults.
149 + var configuration = is.not.existy(options) ? {} : options; // Validation.
150 +
151 + if (is.not.object(configuration)) {
152 + throw new TypeError('Options must be an object!');
153 + }
154 +
155 + var attributeName = configuration.attributeName || 'clientIp';
156 + return function (req, res, next) {
157 + var ip = getClientIp(req);
158 + Object.defineProperty(req, attributeName, {
159 + get: function get() {
160 + return ip;
161 + },
162 + configurable: true
163 + });
164 + next();
165 + };
166 +}
167 +
168 +module.exports = {
169 + getClientIpFromXForwardedFor: getClientIpFromXForwardedFor,
170 + getClientIp: getClientIp,
171 + mw: mw
172 +};
173 +
1 +{
2 + "_from": "request-ip",
3 + "_id": "request-ip@2.1.3",
4 + "_inBundle": false,
5 + "_integrity": "sha512-J3qdE/IhVM3BXkwMIVO4yFrvhJlU3H7JH16+6yHucadT4fePnR8dyh+vEs6FIx0S2x5TCt2ptiPfHcn0sqhbYQ==",
6 + "_location": "/request-ip",
7 + "_phantomChildren": {},
8 + "_requested": {
9 + "type": "tag",
10 + "registry": true,
11 + "raw": "request-ip",
12 + "name": "request-ip",
13 + "escapedName": "request-ip",
14 + "rawSpec": "",
15 + "saveSpec": null,
16 + "fetchSpec": "latest"
17 + },
18 + "_requiredBy": [
19 + "#USER",
20 + "/"
21 + ],
22 + "_resolved": "https://registry.npmjs.org/request-ip/-/request-ip-2.1.3.tgz",
23 + "_shasum": "99ab2bafdeaf2002626e28083cb10597511d9e14",
24 + "_spec": "request-ip",
25 + "_where": "C:\\Users\\KoMoGoon\\Desktop\\oss_project\\Singer-Composer",
26 + "author": {
27 + "name": "Petar Bojinov",
28 + "email": "petarbojinov@gmail.com"
29 + },
30 + "bugs": {
31 + "url": "https://github.com/pbojinov/request-ip/issues"
32 + },
33 + "bundleDependencies": false,
34 + "contributors": [
35 + {
36 + "name": "Jon Peck",
37 + "email": "jpeck@fluxsauce.com"
38 + }
39 + ],
40 + "dependencies": {
41 + "is_js": "^0.9.0"
42 + },
43 + "deprecated": false,
44 + "description": "A small node.js module to retrieve the request's IP address",
45 + "devDependencies": {
46 + "@babel/cli": "^7.0.0-beta.51",
47 + "@babel/core": "^7.0.0-beta.51",
48 + "@babel/preset-env": "^7.0.0-beta.51",
49 + "coveralls": "^3.0.2",
50 + "eslint": "^5.8.0",
51 + "eslint-config-airbnb-base": "^13.1.0",
52 + "eslint-plugin-import": "^2.2.0",
53 + "nyc": "^13.1.0",
54 + "request": "^2.54.0",
55 + "tap-spec": "^5.0.0",
56 + "tape": "^4.9.1"
57 + },
58 + "files": [
59 + "dist"
60 + ],
61 + "homepage": "https://github.com/pbojinov/request-ip",
62 + "keywords": [
63 + "request ip",
64 + "ip",
65 + "address",
66 + "request",
67 + "proxy",
68 + "client",
69 + "header",
70 + "X-Client-IP",
71 + "X-Forwarded-For",
72 + "CF-Connecting-IP",
73 + "Fastly-Client-IP",
74 + "True-Client-IP",
75 + "X-Real-IP",
76 + "X-Cluster-Client-IP",
77 + "X-Forwarded",
78 + "Forwarded-For",
79 + "connection.remoteAddress",
80 + "connection.socket.remoteAddress",
81 + "req.info.remoteAddress",
82 + "middleware",
83 + "ipv4",
84 + "ipv6"
85 + ],
86 + "license": "MIT",
87 + "main": "./dist/index.js",
88 + "name": "request-ip",
89 + "repository": {
90 + "type": "git",
91 + "url": "git+https://github.com/pbojinov/request-ip.git"
92 + },
93 + "scripts": {
94 + "build": "babel ./src/index.js > ./dist/index.js",
95 + "changelog": "github_changelog_generator -u pbojinov -p request-ip",
96 + "coverage": "nyc report --reporter=text-lcov | coveralls",
97 + "test": "nyc --reporter=html --reporter=text --check-coverage --lines=100 --statements=100 tape ./test/index.js"
98 + },
99 + "version": "2.1.3"
100 +}
...@@ -750,6 +750,11 @@ ...@@ -750,6 +750,11 @@
750 "integrity": "sha1-5HnICFjfDBsR3dppQPlgEfzaSpo=", 750 "integrity": "sha1-5HnICFjfDBsR3dppQPlgEfzaSpo=",
751 "dev": true 751 "dev": true
752 }, 752 },
753 + "is_js": {
754 + "version": "0.9.0",
755 + "resolved": "https://registry.npmjs.org/is_js/-/is_js-0.9.0.tgz",
756 + "integrity": "sha1-CrlFQFArp6+iTIVqqYVWFmnpxS0="
757 + },
753 "isarray": { 758 "isarray": {
754 "version": "1.0.0", 759 "version": "1.0.0",
755 "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", 760 "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz",
...@@ -1154,6 +1159,14 @@ ...@@ -1154,6 +1159,14 @@
1154 } 1159 }
1155 } 1160 }
1156 }, 1161 },
1162 + "request-ip": {
1163 + "version": "2.1.3",
1164 + "resolved": "https://registry.npmjs.org/request-ip/-/request-ip-2.1.3.tgz",
1165 + "integrity": "sha512-J3qdE/IhVM3BXkwMIVO4yFrvhJlU3H7JH16+6yHucadT4fePnR8dyh+vEs6FIx0S2x5TCt2ptiPfHcn0sqhbYQ==",
1166 + "requires": {
1167 + "is_js": "^0.9.0"
1168 + }
1169 + },
1157 "request-promise-core": { 1170 "request-promise-core": {
1158 "version": "1.1.4", 1171 "version": "1.1.4",
1159 "resolved": "https://registry.npmjs.org/request-promise-core/-/request-promise-core-1.1.4.tgz", 1172 "resolved": "https://registry.npmjs.org/request-promise-core/-/request-promise-core-1.1.4.tgz",
......
...@@ -12,6 +12,7 @@ ...@@ -12,6 +12,7 @@
12 "ejs": "^3.1.6", 12 "ejs": "^3.1.6",
13 "express": "^4.17.1", 13 "express": "^4.17.1",
14 "mysql": "^2.18.1", 14 "mysql": "^2.18.1",
15 + "request-ip": "^2.1.3",
15 "socket.io": "^4.4.0" 16 "socket.io": "^4.4.0"
16 }, 17 },
17 "devDependencies": { 18 "devDependencies": {
......
...@@ -60,10 +60,10 @@ create table board( ...@@ -60,10 +60,10 @@ create table board(
60 >UPDATE board SET idx = @COUNT:=@COUNT+1; 60 >UPDATE board SET idx = @COUNT:=@COUNT+1;
61 61
62 --- 62 ---
63 -### 최종 수정: 2021-11-23 01:53<br> 63 +### 최종 수정: 2021-11-23 02:49<br>
64 ### 수정 내용: 64 ### 수정 내용:
65 0. 채팅기능에 버그가 있는 것 같음-피드백 바람(undefined님이 나가셨습니다. -> 콘솔에 계속 출력됨) 65 0. 채팅기능에 버그가 있는 것 같음-피드백 바람(undefined님이 나가셨습니다. -> 콘솔에 계속 출력됨)
66 -1. 일부 수정 66 +1. 로그에 IP 추가
67 2. 로그에 시간 추가 67 2. 로그에 시간 추가
68 3. 시간 실시간 반영 68 3. 시간 실시간 반영
69 4. 게시글 수정 및 삭제 세션+권한 연동/DB수정 69 4. 게시글 수정 및 삭제 세션+권한 연동/DB수정
......
...@@ -2,6 +2,7 @@ var express = require('express') ...@@ -2,6 +2,7 @@ var express = require('express')
2 var app = express() 2 var app = express()
3 var router = express.Router(); 3 var router = express.Router();
4 var path = require('path') // 상대경로 4 var path = require('path') // 상대경로
5 +var requestIp = require('request-ip');
5 6
6 // 로그용 7 // 로그용
7 var logString; 8 var logString;
...@@ -24,14 +25,15 @@ init() ...@@ -24,14 +25,15 @@ init()
24 25
25 // main page는 login이 된 상태(세션정보가 있을때만) 접근이 가능하게 하자 -> info에 구현해놓음. 26 // main page는 login이 된 상태(세션정보가 있을때만) 접근이 가능하게 하자 -> info에 구현해놓음.
26 router.get('/', function(req, res){ 27 router.get('/', function(req, res){
28 + var ip = requestIp.getClientIp(req);
27 var id = req.user; 29 var id = req.user;
28 if(!id){ 30 if(!id){
29 - console.log(logString+'익명의 유저가 about 페이지에서 작업 중입니다.') 31 + console.log(logString+'익명의 유저가 about 페이지에서 작업 중입니다.('+ip+')')
30 res.sendFile(path.join(__dirname, "../../public/about.html")) 32 res.sendFile(path.join(__dirname, "../../public/about.html"))
31 } 33 }
32 if(id){ 34 if(id){
33 var nickname = req.user.nickname; 35 var nickname = req.user.nickname;
34 - console.log(logString+req.user.ID+'('+nickname+') 유저가 about 페이지에서 작업 중입니다.') 36 + console.log(logString+req.user.ID+'('+nickname+') 유저가 about 페이지에서 작업 중입니다.('+ip+')')
35 res.render('about.ejs', {'ID': id, 'nickname': nickname}); 37 res.render('about.ejs', {'ID': id, 'nickname': nickname});
36 } 38 }
37 }); 39 });
......
...@@ -7,6 +7,7 @@ var mysql = require('mysql'); ...@@ -7,6 +7,7 @@ var mysql = require('mysql');
7 var path = require('path') // 상대경로 7 var path = require('path') // 상대경로
8 var mysql_odbc = require('../../db/db_board')(); 8 var mysql_odbc = require('../../db/db_board')();
9 var board = mysql_odbc.init(); 9 var board = mysql_odbc.init();
10 +var requestIp = require('request-ip');
10 11
11 // 로그용 12 // 로그용
12 var logString; 13 var logString;
...@@ -28,9 +29,10 @@ function init(){ ...@@ -28,9 +29,10 @@ function init(){
28 init() 29 init()
29 30
30 router.get('/list/:page', function(req, res, next) { 31 router.get('/list/:page', function(req, res, next) {
32 + var ip = requestIp.getClientIp(req);
31 var id = req.user; 33 var id = req.user;
32 if(!id){ 34 if(!id){
33 - console.log(logString+'익명 유저의 게시판 접근을 거부했습니다.') 35 + console.log(logString+'익명 유저의 게시판 접근을 거부했습니다.('+ip+')')
34 res.redirect('/board/list/1') 36 res.redirect('/board/list/1')
35 } 37 }
36 else{ 38 else{
...@@ -41,36 +43,39 @@ router.get('/list/:page', function(req, res, next) { ...@@ -41,36 +43,39 @@ router.get('/list/:page', function(req, res, next) {
41 if (err) console.error("err : " + err); 43 if (err) console.error("err : " + err);
42 var id = req.user.ID; 44 var id = req.user.ID;
43 var nickname = req.user.nickname; 45 var nickname = req.user.nickname;
44 - console.log(logString+req.user.ID+'('+nickname+') 유저가 게시판을 보고있습니다.') 46 + console.log(logString+req.user.ID+'('+nickname+') 유저가 게시판을 보고있습니다.('+ip+')')
45 res.render('list.ejs', {'ID':id, 'nickname': nickname, title: '게시판 리스트', rows: rows, page:page, length:rows.length-1,page_num:10,pass:true}) 47 res.render('list.ejs', {'ID':id, 'nickname': nickname, title: '게시판 리스트', rows: rows, page:page, length:rows.length-1,page_num:10,pass:true})
46 }) 48 })
47 } 49 }
48 }); 50 });
49 51
50 router.get('/list', function(req,res,next){ 52 router.get('/list', function(req,res,next){
53 + var ip = requestIp.getClientIp(req);
51 var id = req.user; 54 var id = req.user;
52 if(!id){ 55 if(!id){
53 - console.log(logString+'익명 유저의 게시판 접근을 거부했습니다.') 56 + console.log(logString+'익명 유저의 게시판 접근을 거부했습니다.('+ip+')')
54 res.sendFile(path.join(__dirname, "../../public/login.html")) 57 res.sendFile(path.join(__dirname, "../../public/login.html"))
55 } 58 }
56 else res.redirect('/board/list/1') 59 else res.redirect('/board/list/1')
57 }) 60 })
58 61
59 router.get('/write', function(req,res,next){ 62 router.get('/write', function(req,res,next){
63 + var ip = requestIp.getClientIp(req);
60 var id = req.user; 64 var id = req.user;
61 if(!id){ 65 if(!id){
62 - console.log(logString+'익명 유저의 글쓰기 시도를 거부했습니다.') 66 + console.log(logString+'익명 유저의 글쓰기 시도를 거부했습니다.('+ip+')')
63 res.sendFile(path.join(__dirname, "../../public/login.html")) 67 res.sendFile(path.join(__dirname, "../../public/login.html"))
64 } 68 }
65 else{ 69 else{
66 var id = req.user.ID; 70 var id = req.user.ID;
67 var nickname = req.user.nickname; 71 var nickname = req.user.nickname;
68 - console.log(logString+req.user.ID+'('+nickname+') 유저가 게시글 작성 중입니다.') 72 + console.log(logString+req.user.ID+'('+nickname+') 유저가 게시글 작성 중입니다.('+ip+')')
69 res.render('write.ejs', {'ID':id, 'nickname': nickname, title:"게시판 글 쓰기"}) 73 res.render('write.ejs', {'ID':id, 'nickname': nickname, title:"게시판 글 쓰기"})
70 } 74 }
71 }) 75 })
72 76
73 router.post('/write', function(req,res,next){ 77 router.post('/write', function(req,res,next){
78 + var ip = requestIp.getClientIp(req);
74 var nickname = req.user.nickname // var name = req.body.name 79 var nickname = req.user.nickname // var name = req.body.name
75 var title = req.body.title 80 var title = req.body.title
76 var content = req.body.content 81 var content = req.body.content
...@@ -91,12 +96,13 @@ router.post('/write', function(req,res,next){ ...@@ -91,12 +96,13 @@ router.post('/write', function(req,res,next){
91 if(!idx_) // 글이 없으면 NULL 96 if(!idx_) // 글이 없으면 NULL
92 idx_ = 1; 97 idx_ = 1;
93 98
94 - console.log(logString+req.user.ID+'('+nickname+') 유저가 '+idx_+'번 게시글을 작성했습니다.') 99 + console.log(logString+req.user.ID+'('+nickname+') 유저가 '+idx_+'번 게시글을 작성했습니다.('+ip+')')
95 res.redirect('/board/read/'+idx_); 100 res.redirect('/board/read/'+idx_);
96 }); 101 });
97 }) 102 })
98 103
99 router.get('/read/:idx', function(req,res,next){ 104 router.get('/read/:idx', function(req,res,next){
105 + var ip = requestIp.getClientIp(req);
100 var idx = req.params.idx 106 var idx = req.params.idx
101 var sql = "select idx, nickname, title, content, date_format(modidate,'%Y-%m-%d %H:%i:%s') modidate, " + 107 var sql = "select idx, nickname, title, content, date_format(modidate,'%Y-%m-%d %H:%i:%s') modidate, " +
102 "date_format(regdate,'%Y-%m-%d %H:%i:%s') regdate, hit, ID from board where idx=?"; 108 "date_format(regdate,'%Y-%m-%d %H:%i:%s') regdate, hit, ID from board where idx=?";
...@@ -105,7 +111,7 @@ router.get('/read/:idx', function(req,res,next){ ...@@ -105,7 +111,7 @@ router.get('/read/:idx', function(req,res,next){
105 111
106 var id = req.user; 112 var id = req.user;
107 if(!id){ 113 if(!id){
108 - console.log(logString+'익명 유저의 '+idx+'번 게시물 접근을 거부했습니다.') 114 + console.log(logString+'익명 유저의 '+idx+'번 게시물 접근을 거부했습니다.('+ip+')')
109 res.redirect('/login') 115 res.redirect('/login')
110 } 116 }
111 else{ 117 else{
...@@ -118,13 +124,14 @@ router.get('/read/:idx', function(req,res,next){ ...@@ -118,13 +124,14 @@ router.get('/read/:idx', function(req,res,next){
118 if(err) console.error(err) 124 if(err) console.error(err)
119 }) 125 })
120 126
121 - console.log(logString+req.user.ID+'('+nickname+') 유저가 '+idx+'번 게시글을 보고있습니다.') 127 + console.log(logString+req.user.ID+'('+nickname+') 유저가 '+idx+'번 게시글을 보고있습니다.('+ip+')')
122 res.render('read.ejs', {'ID':id, 'nickname': nickname, title:"글 상세", row:row[0]}) 128 res.render('read.ejs', {'ID':id, 'nickname': nickname, title:"글 상세", row:row[0]})
123 } 129 }
124 }) 130 })
125 }) 131 })
126 132
127 router.post('/update', function(req,res,next){ 133 router.post('/update', function(req,res,next){
134 + var ip = requestIp.getClientIp(req);
128 var ID = req.user.ID; 135 var ID = req.user.ID;
129 var idx = req.body.idx 136 var idx = req.body.idx
130 var title = req.body.title 137 var title = req.body.title
...@@ -135,19 +142,20 @@ router.post('/update', function(req,res,next){ ...@@ -135,19 +142,20 @@ router.post('/update', function(req,res,next){
135 board.query(sql,datas,function(err,result){ 142 board.query(sql,datas,function(err,result){
136 if(err) console.error(err) 143 if(err) console.error(err)
137 if(result.affectedRows==0){ 144 if(result.affectedRows==0){
138 - console.log(logString+req.user.ID+'('+nickname+') 유저의 '+idx+'번 게시글 수정을 거부했습니다.(권한없음)') 145 + console.log(logString+req.user.ID+'('+req.user.nickname+') 유저의 '+idx+'번 게시글 수정을 거부했습니다.(권한없음 // '+ip+')')
139 res.send("<script>alert('게시글 작성자가 아닙니다.');history.back();</script>") 146 res.send("<script>alert('게시글 작성자가 아닙니다.');history.back();</script>")
140 } 147 }
141 else{ 148 else{
142 var id = req.user.ID; 149 var id = req.user.ID;
143 var nickname = req.user.nickname; 150 var nickname = req.user.nickname;
144 - console.log(logString+req.user.ID+'('+nickname+') 유저가 '+idx+'번 게시글을 수정했습니다.') 151 + console.log(logString+req.user.ID+'('+nickname+') 유저가 '+idx+'번 게시글을 수정했습니다.('+ip+')')
145 res.redirect('/board/read/'+idx) 152 res.redirect('/board/read/'+idx)
146 } 153 }
147 }) 154 })
148 }) 155 })
149 156
150 router.post('/delete', function(req,res,next){ 157 router.post('/delete', function(req,res,next){
158 + var ip = requestIp.getClientIp(req);
151 var idx = req.body.idx 159 var idx = req.body.idx
152 var ID = req.user.ID; 160 var ID = req.user.ID;
153 var datas = [idx,ID] 161 var datas = [idx,ID]
...@@ -170,12 +178,12 @@ router.post('/delete', function(req,res,next){ ...@@ -170,12 +178,12 @@ router.post('/delete', function(req,res,next){
170 178
171 var nickname = req.user.nickname; 179 var nickname = req.user.nickname;
172 res.send("<script>alert('게시글이 운영자에 의해 삭제되었습니다.');window.location.href='/board/list/';</script>"); 180 res.send("<script>alert('게시글이 운영자에 의해 삭제되었습니다.');window.location.href='/board/list/';</script>");
173 - console.log(logString+"[Admin] "+req.user.ID+'('+nickname+') 유저가 '+idx+'번 게시글을 삭제했습니다.') 181 + console.log(logString+"[Admin] "+req.user.ID+'('+nickname+') 유저가 '+idx+'번 게시글을 삭제했습니다.('+ip+')')
174 }) 182 })
175 } 183 }
176 else{ // 작성자도, 운영자도 아니면 184 else{ // 작성자도, 운영자도 아니면
177 var nickname = req.user.nickname; 185 var nickname = req.user.nickname;
178 - console.log(logString+req.user.ID+'('+nickname+') 유저의 '+idx+'번 게시글 삭제를 거부했습니다.(권한없음)') 186 + console.log(logString+req.user.ID+'('+nickname+') 유저의 '+idx+'번 게시글 삭제를 거부했습니다.(권한없음 // '+ip+')')
179 res.send("<script>alert('게시글 작성자가 아닙니다');history.back();</script>"); 187 res.send("<script>alert('게시글 작성자가 아닙니다');history.back();</script>");
180 } 188 }
181 }) 189 })
...@@ -184,7 +192,7 @@ router.post('/delete', function(req,res,next){ ...@@ -184,7 +192,7 @@ router.post('/delete', function(req,res,next){
184 var id = req.user.ID; 192 var id = req.user.ID;
185 var nickname = req.user.nickname; 193 var nickname = req.user.nickname;
186 res.send("<script>alert('게시글이 삭제되었습니다.');window.location.href='/board/list/';</script>"); 194 res.send("<script>alert('게시글이 삭제되었습니다.');window.location.href='/board/list/';</script>");
187 - console.log(logString+req.user.ID+'('+nickname+') 유저가 '+idx+'번 게시글을 삭제했습니다.') 195 + console.log(logString+req.user.ID+'('+nickname+') 유저가 '+idx+'번 게시글을 삭제했습니다.('+ip+')')
188 } 196 }
189 }) 197 })
190 }) 198 })
......
...@@ -4,6 +4,7 @@ var router = express.Router(); ...@@ -4,6 +4,7 @@ var router = express.Router();
4 var path = require('path') // 상대경로 4 var path = require('path') // 상대경로
5 var mysql_odbc = require('../../db/db_board')(); 5 var mysql_odbc = require('../../db/db_board')();
6 var myinfo = mysql_odbc.init(); 6 var myinfo = mysql_odbc.init();
7 +var requestIp = require('request-ip');
7 8
8 // 로그용 9 // 로그용
9 var logString; 10 var logString;
...@@ -25,14 +26,15 @@ function init(){ ...@@ -25,14 +26,15 @@ function init(){
25 init() 26 init()
26 27
27 router.get('/', function(req, res){ 28 router.get('/', function(req, res){
29 + var ip = requestIp.getClientIp(req);
28 var id = req.user; 30 var id = req.user;
29 if(!id){ 31 if(!id){
30 - console.log(logString+'익명 유저의 채팅 접근을 거부했습니다.') 32 + console.log(logString+'익명 유저의 채팅 접근을 거부했습니다.('+ip+')')
31 res.sendFile(path.join(__dirname, "../../public/login.html")) 33 res.sendFile(path.join(__dirname, "../../public/login.html"))
32 } 34 }
33 if(id){ 35 if(id){
34 var nickname = req.user.nickname 36 var nickname = req.user.nickname
35 - console.log(logString+req.user.ID+'('+nickname+') 유저가 채팅 중입니다.') 37 + console.log(logString+req.user.ID+'('+nickname+') 유저가 채팅 중입니다.('+ip+')')
36 res.render('chat.ejs', {'nickname':nickname}) 38 res.render('chat.ejs', {'nickname':nickname})
37 } 39 }
38 }); 40 });
......
...@@ -2,6 +2,7 @@ var express = require('express') ...@@ -2,6 +2,7 @@ var express = require('express')
2 var app = express() 2 var app = express()
3 var router = express.Router(); 3 var router = express.Router();
4 var path = require('path') 4 var path = require('path')
5 +var requestIp = require('request-ip');
5 6
6 var main = require('./main/main') 7 var main = require('./main/main')
7 var register = require('./register/index') 8 var register = require('./register/index')
...@@ -12,10 +13,39 @@ var profile = require('./profile/index') ...@@ -12,10 +13,39 @@ var profile = require('./profile/index')
12 var about = require('./about/index') 13 var about = require('./about/index')
13 var chat = require('./chat/chat') 14 var chat = require('./chat/chat')
14 15
16 +// 로그용
17 +var logString;
18 +function getTime(){
19 + var today = new Date();
20 + var year = today.getFullYear();
21 + var month = ('0' + (today.getMonth()+1)).slice(-2);
22 + var day = ('0' + today.getDate()).slice(-2);
23 + var hour = ('0' + today.getHours()).slice(-2);
24 + var minute = ('0' + today.getMinutes()).slice(-2);
25 + var second = ('0' + today.getSeconds()).slice(-2);
26 + logString = '['+year+'-'+month+'-'+day+' '+hour+':'+minute+':'+second+'] ';
27 +}
28 +// 시간 갱신용
29 +function init(){
30 + getTime();
31 + setInterval(getTime, 1000)
32 +}
33 +init()
34 +
15 // URL routing 35 // URL routing
16 // req = request, res = respond 36 // req = request, res = respond
17 router.get('/', function(req, res){ 37 router.get('/', function(req, res){
18 - res.sendFile(path.join(__dirname, "../public/main.html")); 38 + var ip = requestIp.getClientIp(req);
39 + var id = req.user;
40 + if(!id){
41 + console.log(logString+'익명의 유저가 작업 중입니다.('+ip+')')
42 + res.sendFile(path.join(__dirname, "../public/main.html"))
43 + }
44 + if(id){
45 + var nickname = req.user.nickname;
46 + console.log(logString+req.user.ID+'('+nickname+') 유저가 작업 중입니다.('+ip+')')
47 + res.render('main.ejs', {'ID': id, 'nickname': nickname});
48 + }
19 }); 49 });
20 50
21 // router 정의 51 // router 정의
......
...@@ -5,6 +5,7 @@ var path = require('path') // 상대경로 ...@@ -5,6 +5,7 @@ var path = require('path') // 상대경로
5 var mysql = require('mysql') 5 var mysql = require('mysql')
6 var passport = require('passport') 6 var passport = require('passport')
7 var LocalStrategy = require('passport-local').Strategy 7 var LocalStrategy = require('passport-local').Strategy
8 +var requestIp = require('request-ip');
8 9
9 // 로그용 10 // 로그용
10 var logString; 11 var logString;
...@@ -39,7 +40,8 @@ router.get('/', function(req, res){ ...@@ -39,7 +40,8 @@ router.get('/', function(req, res){
39 var msg; 40 var msg;
40 var errMsg = req.flash('error') 41 var errMsg = req.flash('error')
41 if(errMsg) msg = errMsg; 42 if(errMsg) msg = errMsg;
42 - console.log(logString+'익명의 유저가 로그인 중입니다.') 43 + var ip = requestIp.getClientIp(req);
44 + console.log(logString+'익명의 유저가 로그인 중입니다.('+ip+')')
43 res.render('login.ejs', {'message' : msg}); 45 res.render('login.ejs', {'message' : msg});
44 }) 46 })
45 47
...@@ -62,18 +64,19 @@ passport.use('local-login', new LocalStrategy({ ...@@ -62,18 +64,19 @@ passport.use('local-login', new LocalStrategy({
62 var query = connection.query('select * from userDB where ID=?', [ID], function(err, rows){ 64 var query = connection.query('select * from userDB where ID=?', [ID], function(err, rows){
63 if(err) return done(err); 65 if(err) return done(err);
64 66
67 + var ip = requestIp.getClientIp(req);
65 if(rows.length){ // database에 입력한 ID값이 있는가? 68 if(rows.length){ // database에 입력한 ID값이 있는가?
66 if(password == rows[0].password){ // 비밀번호와 확인이 같은가? 69 if(password == rows[0].password){ // 비밀번호와 확인이 같은가?
67 - console.log(logString+"로그인 알림: "+ ID +"(" + rows[0].nickname + ")") 70 + console.log(logString+"로그인 알림: "+ ID +"(" + rows[0].nickname +" // "+ip+')')
68 return done(null, {'ID' : ID, 'nickname' : rows[0].nickname}); 71 return done(null, {'ID' : ID, 'nickname' : rows[0].nickname});
69 } 72 }
70 else{ 73 else{
71 - console.log(logString+"로그인 알림: 잘못된 비밀번호입니다.(시도된 아이디: "+ID+")") 74 + console.log(logString+"로그인 알림: 잘못된 비밀번호입니다.(시도된 아이디: "+ID+" // "+ip+')')
72 return done(null, false, {message : '잘못된 비밀번호입니다.'}) 75 return done(null, false, {message : '잘못된 비밀번호입니다.'})
73 } 76 }
74 } 77 }
75 else{ 78 else{
76 - console.log(logString+"로그인 알림: ID를 찾을 수 없습니다.(시도된 아이디: "+ID+")") 79 + console.log(logString+"로그인 알림: ID를 찾을 수 없습니다.(시도된 아이디: "+ID+" // "+ip+')')
77 return done(null, false, {message : 'ID를 찾을 수 없습니다.'}) 80 return done(null, false, {message : 'ID를 찾을 수 없습니다.'})
78 } 81 }
79 }) 82 })
......
...@@ -2,6 +2,7 @@ var express = require('express') ...@@ -2,6 +2,7 @@ var express = require('express')
2 var app = express() 2 var app = express()
3 var router = express.Router(); 3 var router = express.Router();
4 var path = require('path') 4 var path = require('path')
5 +var requestIp = require('request-ip');
5 6
6 // 로그용 7 // 로그용
7 var logString; 8 var logString;
...@@ -23,13 +24,14 @@ function init(){ ...@@ -23,13 +24,14 @@ function init(){
23 init() 24 init()
24 25
25 router.get('/', function(req, res){ 26 router.get('/', function(req, res){
27 + var ip = requestIp.getClientIp(req);
26 var id = req.user; 28 var id = req.user;
27 if(!id){ 29 if(!id){
28 - console.log(logString+"익명 유저의 로그아웃 시도를 거부했습니다.") 30 + console.log(logString+"익명 유저의 로그아웃 시도를 거부했습니다.("+ip+')')
29 res.redirect('/main') 31 res.redirect('/main')
30 } 32 }
31 else{ 33 else{
32 - console.log(logString+req.user.ID+"("+req.user.nickname+") 유저가 로그아웃합니다.") 34 + console.log(logString+req.user.ID+"("+req.user.nickname+") 유저가 로그아웃합니다.("+ip+')')
33 req.logout(); 35 req.logout();
34 req.session.save(function(){ 36 req.session.save(function(){
35 res.redirect('/'); 37 res.redirect('/');
......
...@@ -2,6 +2,7 @@ var express = require('express') ...@@ -2,6 +2,7 @@ var express = require('express')
2 var app = express() 2 var app = express()
3 var router = express.Router(); 3 var router = express.Router();
4 var path = require('path') // 상대경로 4 var path = require('path') // 상대경로
5 +var requestIp = require('request-ip');
5 6
6 // 로그용 7 // 로그용
7 var logString; 8 var logString;
...@@ -24,14 +25,15 @@ init() ...@@ -24,14 +25,15 @@ init()
24 25
25 // main page는 login이 된 상태(세션정보가 있을때만) 접근이 가능하게 하자 -> info에 구현해놓음. 26 // main page는 login이 된 상태(세션정보가 있을때만) 접근이 가능하게 하자 -> info에 구현해놓음.
26 router.get('/', function(req, res){ 27 router.get('/', function(req, res){
28 + var ip = requestIp.getClientIp(req);
27 var id = req.user; 29 var id = req.user;
28 if(!id){ 30 if(!id){
29 - console.log(logString+'익명의 유저가 작업 중입니다.') 31 + console.log(logString+'익명의 유저가 작업 중입니다.('+ip+')')
30 res.sendFile(path.join(__dirname, "../../public/main.html")) 32 res.sendFile(path.join(__dirname, "../../public/main.html"))
31 } 33 }
32 if(id){ 34 if(id){
33 var nickname = req.user.nickname; 35 var nickname = req.user.nickname;
34 - console.log(logString+req.user.ID+'('+nickname+') 유저가 작업 중입니다.') 36 + console.log(logString+req.user.ID+'('+nickname+') 유저가 작업 중입니다.('+ip+')')
35 res.render('main.ejs', {'ID': id, 'nickname': nickname}); 37 res.render('main.ejs', {'ID': id, 'nickname': nickname});
36 } 38 }
37 }); 39 });
......
...@@ -6,6 +6,7 @@ var mysql_odbc = require('../../db/db_board')(); ...@@ -6,6 +6,7 @@ var mysql_odbc = require('../../db/db_board')();
6 var myinfo = mysql_odbc.init(); 6 var myinfo = mysql_odbc.init();
7 var passport = require('passport') 7 var passport = require('passport')
8 var LocalStrategy = require('passport-local').Strategy 8 var LocalStrategy = require('passport-local').Strategy
9 +var requestIp = require('request-ip');
9 10
10 // 로그용 11 // 로그용
11 var logString; 12 var logString;
...@@ -39,6 +40,7 @@ passport.deserializeUser(function(user, done){ ...@@ -39,6 +40,7 @@ passport.deserializeUser(function(user, done){
39 40
40 // main page는 login이 된 상태(세션정보가 있을때만) 접근이 가능하게 하자 -> info에 구현해놓음. 41 // main page는 login이 된 상태(세션정보가 있을때만) 접근이 가능하게 하자 -> info에 구현해놓음.
41 router.get('/', function(req, res){ 42 router.get('/', function(req, res){
43 + var ip = requestIp.getClientIp(req);
42 try{ 44 try{
43 var id = req.session.passport.user.ID; 45 var id = req.session.passport.user.ID;
44 // if(!id){ 46 // if(!id){
...@@ -53,18 +55,19 @@ router.get('/', function(req, res){ ...@@ -53,18 +55,19 @@ router.get('/', function(req, res){
53 var nickname = req.user.nickname; 55 var nickname = req.user.nickname;
54 var type = rows[0].type; 56 var type = rows[0].type;
55 var profilemsg = rows[0].profilemsg; 57 var profilemsg = rows[0].profilemsg;
56 - console.log(logString+req.user.ID+'('+nickname+') 유저가 프로필을 보고있습니다.') 58 + console.log(logString+req.user.ID+'('+nickname+') 유저가 프로필을 보고있습니다.('+ip+')')
57 res.render('profile.ejs', {'ID':id, 'nickname': nickname, 'type': type, 'profilemsg': profilemsg}) 59 res.render('profile.ejs', {'ID':id, 'nickname': nickname, 'type': type, 'profilemsg': profilemsg})
58 }) 60 })
59 } 61 }
60 catch{ 62 catch{
61 - console.log(logString+'익명 유저의 프로필 접근 시도를 거부했습니다.') 63 + console.log(logString+'익명 유저의 프로필 접근 시도를 거부했습니다.('+ip+')')
62 res.sendFile(path.join(__dirname, "../../public/login.html")) 64 res.sendFile(path.join(__dirname, "../../public/login.html"))
63 } 65 }
64 66
65 }); 67 });
66 68
67 router.get('/update', function(req,res){ 69 router.get('/update', function(req,res){
70 + var ip = requestIp.getClientIp(req);
68 try{ 71 try{
69 var id = req.user.ID; 72 var id = req.user.ID;
70 // if(!id){ 73 // if(!id){
...@@ -80,19 +83,20 @@ router.get('/update', function(req,res){ ...@@ -80,19 +83,20 @@ router.get('/update', function(req,res){
80 var nickname = req.user.nickname; 83 var nickname = req.user.nickname;
81 var type = req.user.type; 84 var type = req.user.type;
82 var profilemsg = rows[0].profilemsg; 85 var profilemsg = rows[0].profilemsg;
83 - console.log(logString+req.user.ID+'('+nickname+') 유저가 프로필 수정 중입니다.') 86 + console.log(logString+req.user.ID+'('+nickname+') 유저가 프로필 수정 중입니다.('+ip+')')
84 res.render('profmsgedit.ejs', {'ID':id, 'nickname': nickname, 'type':type, 'profilemsg': profilemsg, 'message':''}); 87 res.render('profmsgedit.ejs', {'ID':id, 'nickname': nickname, 'type':type, 'profilemsg': profilemsg, 'message':''});
85 }) 88 })
86 } 89 }
87 catch{ 90 catch{
88 if(!id){ 91 if(!id){
89 - console.log(logString+'익명 유저의 프로필 수정 시도를 거부했습니다.') 92 + console.log(logString+'익명 유저의 프로필 수정 시도를 거부했습니다.('+ip+')')
90 res.sendFile(path.join(__dirname, "../../public/login.html")) 93 res.sendFile(path.join(__dirname, "../../public/login.html"))
91 } 94 }
92 } 95 }
93 }) 96 })
94 97
95 router.post('/update', function(req,res,next){ 98 router.post('/update', function(req,res,next){
99 + var ip = requestIp.getClientIp(req);
96 var id = req.user.ID; 100 var id = req.user.ID;
97 var profilemsg = req.body.profilemsg; 101 var profilemsg = req.body.profilemsg;
98 var nickname = req.body.nickname; 102 var nickname = req.body.nickname;
...@@ -127,7 +131,7 @@ router.post('/update', function(req,res,next){ ...@@ -127,7 +131,7 @@ router.post('/update', function(req,res,next){
127 myinfo.query(sql,datas,function(err,result){ 131 myinfo.query(sql,datas,function(err,result){
128 if(err) console.error(err) 132 if(err) console.error(err)
129 133
130 - console.log(logString+req.user.ID+'('+req.session.passport.user.nickname+') 유저가 프로필을 수정했습니다.') 134 + console.log(logString+req.user.ID+'('+req.session.passport.user.nickname+') 유저가 프로필을 수정했습니다.('+ip+')')
131 console.log(" ▷ 변경전: "+id+"("+req.user.nickname+") "+oldType+" // "+oldProfilemsg) 135 console.log(" ▷ 변경전: "+id+"("+req.user.nickname+") "+oldType+" // "+oldProfilemsg)
132 req.session.passport.user.nickname = nickname; 136 req.session.passport.user.nickname = nickname;
133 console.log(" ▶ 변경후: "+id+"("+nickname+") "+type+" // "+profilemsg) 137 console.log(" ▶ 변경후: "+id+"("+nickname+") "+type+" // "+profilemsg)
...@@ -135,7 +139,7 @@ router.post('/update', function(req,res,next){ ...@@ -135,7 +139,7 @@ router.post('/update', function(req,res,next){
135 }) 139 })
136 } 140 }
137 else{ // 다른 유저의 닉네임과 중복되는 경우 141 else{ // 다른 유저의 닉네임과 중복되는 경우
138 - console.log(logString+id+" 유저가 중복된 닉네임으로 변경을 시도했습니다.(시도한 닉네임: "+req.body.nickname+")") 142 + console.log(logString+id+" 유저가 중복된 닉네임으로 변경을 시도했습니다.(시도한 닉네임: "+req.body.nickname+" // ("+ip+')')
139 res.render('profmsgedit.ejs', {nickname: req.session.passport.user.nickname, profilemsg: oldProfilemsg, message : '중복된 닉네임입니다.'}) 143 res.render('profmsgedit.ejs', {nickname: req.session.passport.user.nickname, profilemsg: oldProfilemsg, message : '중복된 닉네임입니다.'})
140 } 144 }
141 }) 145 })
......
...@@ -5,6 +5,7 @@ var path = require('path') // 상대경로 ...@@ -5,6 +5,7 @@ var path = require('path') // 상대경로
5 var mysql = require('mysql') 5 var mysql = require('mysql')
6 var passport = require('passport') 6 var passport = require('passport')
7 var LocalStrategy = require('passport-local').Strategy 7 var LocalStrategy = require('passport-local').Strategy
8 +var requestIp = require('request-ip');
8 9
9 // 로그용 10 // 로그용
10 var logString; 11 var logString;
...@@ -39,7 +40,8 @@ router.get('/', function(req, res){ ...@@ -39,7 +40,8 @@ router.get('/', function(req, res){
39 var msg; 40 var msg;
40 var errMsg = req.flash('error') 41 var errMsg = req.flash('error')
41 if(errMsg) msg = errMsg; 42 if(errMsg) msg = errMsg;
42 - console.log(logString+'익명의 유저가 회원가입 중입니다.') 43 + var ip = requestIp.getClientIp(req);
44 + console.log(logString+'익명의 유저가 회원가입 중입니다.('+ip+')')
43 res.render('register.ejs', {'message' : msg}); 45 res.render('register.ejs', {'message' : msg});
44 }) 46 })
45 47
...@@ -63,29 +65,30 @@ passport.use('local-join', new LocalStrategy({ ...@@ -63,29 +65,30 @@ passport.use('local-join', new LocalStrategy({
63 passReqToCallback: true 65 passReqToCallback: true
64 }, function(req, ID, password, done){ 66 }, function(req, ID, password, done){
65 var query = connection.query('select * from userDB where ID=?', [ID], function(err, rows){ 67 var query = connection.query('select * from userDB where ID=?', [ID], function(err, rows){
66 - if(err) return done(err); 68 + var ip = requestIp.getClientIp(req);
69 + if(err) return done(err);
67 70
68 if(rows.length){ // database에 입력한 ID값이 있는가? 71 if(rows.length){ // database에 입력한 ID값이 있는가?
69 - console.log(logString+"회원가입 알림: 중복된 ID입니다.("+ID+")") 72 + console.log(logString+"회원가입 알림: 중복된 ID입니다.("+ID+" // "+ip+')')
70 return done(null, false, {message : '중복된 ID입니다.'}) 73 return done(null, false, {message : '중복된 ID입니다.'})
71 } 74 }
72 else{ 75 else{
73 if(password != req.body.pw_com){ // 비밀번호와 확인이 같지 않은가? 76 if(password != req.body.pw_com){ // 비밀번호와 확인이 같지 않은가?
74 - console.log(logString+"회원가입 알림: 비밀번호가 일치하지 않습니다.(시도 중인 아이디: "+ID+")") 77 + console.log(logString+"회원가입 알림: 비밀번호가 일치하지 않습니다.(시도 중인 아이디: "+ID+" // "+ip+')')
75 return done(null, false, {message : '비밀번호가 일치하지 않습니다.'}) 78 return done(null, false, {message : '비밀번호가 일치하지 않습니다.'})
76 } 79 }
77 else{ 80 else{
78 var subqry = connection.query('select * from userDB where nickname=?', [req.body.nickname], function(err, rows_){ 81 var subqry = connection.query('select * from userDB where nickname=?', [req.body.nickname], function(err, rows_){
79 if(err) return done(err); 82 if(err) return done(err);
80 if(rows_.length){ 83 if(rows_.length){
81 - console.log(logString+"회원가입 알림: 중복된 닉네임입니다.("+req.body.nickname+")") 84 + console.log(logString+"회원가입 알림: 중복된 닉네임입니다.("+req.body.nickname+" // "+ip+')')
82 return done(null, false, {message : '중복된 닉네임입니다.'}) 85 return done(null, false, {message : '중복된 닉네임입니다.'})
83 } 86 }
84 else{ 87 else{
85 var sql = {ID: ID, password: password, type:req.body.type, nickname:req.body.nickname}; 88 var sql = {ID: ID, password: password, type:req.body.type, nickname:req.body.nickname};
86 var query = connection.query('insert into userDB set ?', sql, function(err, rows){ 89 var query = connection.query('insert into userDB set ?', sql, function(err, rows){
87 if(err) throw err 90 if(err) throw err
88 - console.log(logString+"회원가입 알림: 사용자가 추가되었습니다.(" + ID +", " + req.body.nickname + ")") 91 + console.log(logString+"회원가입 알림: 사용자가 추가되었습니다.(" + ID +", " + req.body.nickname + " // "+ip+')')
89 return done(null, {'ID' : ID, 'nickname' : req.body.nickname}); 92 return done(null, {'ID' : ID, 'nickname' : req.body.nickname});
90 }) 93 })
91 } 94 }
......