유희정

kakao login

Showing 53 changed files with 1958 additions and 6 deletions
...@@ -9,6 +9,7 @@ var index = require('./routes/index'); ...@@ -9,6 +9,7 @@ var index = require('./routes/index');
9 var users = require('./routes/users'); 9 var users = require('./routes/users');
10 var calendar = require('./routes/calendar'); 10 var calendar = require('./routes/calendar');
11 var events = require('./routes/events'); 11 var events = require('./routes/events');
12 +var login = require('./routes/login')
12 13
13 passport.serializeUser(function(user,done) { 14 passport.serializeUser(function(user,done) {
14 console.log('serialized'); 15 console.log('serialized');
...@@ -44,6 +45,7 @@ app.use('/', index); ...@@ -44,6 +45,7 @@ app.use('/', index);
44 app.use('/users', users); 45 app.use('/users', users);
45 app.use('/calendar',calendar); 46 app.use('/calendar',calendar);
46 app.use('/events',events); 47 app.use('/events',events);
48 +app.use('/login',login);
47 49
48 // catch 404 and forward to error handler 50 // catch 404 and forward to error handler
49 app.use(function(req, res, next) { 51 app.use(function(req, res, next) {
......
1 +{
2 + "trailingComma": "es5",
3 + "semi": false,
4 + "singleQuote": true,
5 + "arrowParens": "avoid",
6 + "bracketSpacing": true,
7 + "endOfLine": "auto",
8 + "htmlWhitespaceSensitivity": "css",
9 + "proseWrap": "preserve",
10 + "quoteProps": "as-needed",
11 + "tabWidth": 2
12 +}
1 +language: node_js
2 +node_js:
3 + - '0.10'
4 +before_script:
5 + - npm install -g jasmine-node
6 +
1 +# passport-kakao
2 +
3 +kakao oauth2 로그인과 passport 모듈 연결체.
4 +
5 +## install
6 +
7 +```sh
8 +npm install passport-kakao
9 +```
10 +
11 +## how to use
12 +
13 +- https://developers.kakao.com/ 에서 애플리케이션을 등록한다.
14 +- 방금 추가한 애플리케이션의 설정 - 사용자 관리에 들어가서 사용을 ON으로 한 뒤 저장한다.
15 +- 설정 - 일반에서, 플랫폼 추가를 누른 후 웹 플랫폼을 추가한다.
16 +- 웹 플랫폼 설정의 사이트 도메인에 자신의 사이트 도메인을 추가한다. (ex : http://localhost:3000)
17 +- 프로그램 상에서는 아래와 같이 사용한다.
18 +
19 +> clientSecret을 활성화 한 경우 해당 파라메터를 같이 넘겨줘야한다.
20 +
21 +```javascript
22 +const passport = require('passport')
23 +const KakaoStrategy = require('passport-kakao').Strategy
24 +
25 +passport.use(new KakaoStrategy({
26 + clientID : clientID,
27 + clientSecret: clientSecret, // clientSecret을 사용하지 않는다면 넘기지 말거나 빈 스트링을 넘길 것
28 + callbackURL : callbackURL
29 + },
30 + (accessToken, refreshToken, profile, done) => {
31 + // 사용자의 정보는 profile에 들어있다.
32 + User.findOrCreate(..., (err, user) => {
33 + if (err) { return done(err) }
34 + return done(null, user)
35 + })
36 + }
37 +))
38 +```
39 +
40 +> 기본 callbackPath는 `/oauth` 이고 https://developers.kakao.com 에서 수정할 수 있다. 하지만 callbackURL은 `사이트 도메인/oauth` 로 설정하는 것을 권장함. (ex : http://myhomepage.com:3000/oauth )
41 +
42 +##
43 +
44 +## profile property
45 +
46 +profile에는 아래의 property들이 설정되어 넘겨진다.
47 +
48 +| key | value | 비고 |
49 +| -------- | ------ | ------------------------------------------ |
50 +| provider | String | kakao 고정 |
51 +| id | Number | 사용자의 kakao id |
52 +| \_raw | String | 사용자 정보 조회로 얻어진 json string |
53 +| \_json | Object | 사용자 정보 조회로 얻어진 json 원본 데이터 |
54 +
55 +## simple sample
56 +
57 +### 설치 & 실행
58 +
59 +1. `./sample/sample.js``appKey` 를 https://developers.kakao.com 에서 발급받은 JS appKey 값으로 셋팅.
60 +2. command line 에서 아래의 커맨드 실행
61 +3. 브라우져를 열고 `127.0.0.1:3000/login` 을 입력 후 이후 과정을 진행한다.
62 +
63 +```
64 +cd ./sample
65 +npm install
66 +node app
67 +```
68 +
69 +## mean.io 와 쉽게 연동하기
70 +
71 +수정해야하는 파일들은 아래와 같다.
72 +
73 +| file path | 설명 |
74 +| -------------------------------- | ------------------------------ |
75 +| server/config/env/development.js | 개발환경 설정파일 |
76 +| server/config/env/production.js | 운영환경 설정파일 |
77 +| server/config/models/user.js | 사용자 모델 |
78 +| server/config/passport.js | passport script |
79 +| server/routes/users.js | 사용자 로그인 관련 routes file |
80 +| public/auth/views/index.html | 로그인 화면 |
81 +
82 +(1) **mean.io app을 생성** 한다. (ex : mean init kakaoTest)
83 +
84 +(2) 해당 모듈을 연동할 mean.io app에 설치한다.(npm install passport-kakao --save)
85 +
86 +(3) **server/config/env/development.js****production.js** 에 kakao 관련 설정을 아래와 같이 추가한다.
87 +
88 +```javascript
89 +'use strict'
90 +
91 +module.exports = {
92 + db: 'mongodb',
93 + app: {
94 + name: 'passport-kakao',
95 + },
96 + // 그외 설정들....,
97 + kakao: {
98 + clientID: 'kakao app rest api key',
99 + callbackURL: 'http://localhost:3000/oauth',
100 + },
101 +}
102 +```
103 +
104 +(4) **server/config/models/users.js** 의 사용자 스키마 정의에 **kakao: {}** 를 추가한다.
105 +
106 +(5) **server/config/passport.js** 파일에 아래 구문을 추가한다.
107 +
108 +```javascript
109 +// 최상단 require되는 구문에 추가
110 +var KakaoStrategy = require('passport-kakao').Strategy
111 +
112 +passport.use(
113 + new KakaoStrategy(
114 + {
115 + clientID: config.kakao.clientID,
116 + callbackURL: config.kakao.callbackURL,
117 + },
118 + function(accessToken, refreshToken, profile, done) {
119 + User.findOne(
120 + {
121 + 'kakao.id': profile.id,
122 + },
123 + function(err, user) {
124 + if (err) {
125 + return done(err)
126 + }
127 + if (!user) {
128 + user = new User({
129 + name: profile.username,
130 + username: profile.id,
131 + roles: ['authenticated'],
132 + provider: 'kakao',
133 + kakao: profile._json,
134 + })
135 +
136 + user.save(function(err) {
137 + if (err) {
138 + console.log(err)
139 + }
140 + return done(err, user)
141 + })
142 + } else {
143 + return done(err, user)
144 + }
145 + }
146 + )
147 + }
148 + )
149 +)
150 +```
151 +
152 +(6) **server/routes/users.js** 에 아래와 같은 구문을 추가한다.
153 +
154 +```javascript
155 +app.get(
156 + '/auth/kakao',
157 + passport.authenticate('kakao', {
158 + failureRedirect: '#!/login',
159 + }),
160 + users.signin
161 +)
162 +
163 +app.get(
164 + '/oauth',
165 + passport.authenticate('kakao', {
166 + failureRedirect: '#!/login',
167 + }),
168 + users.authCallback
169 +)
170 +```
171 +
172 +(7) **public/auth/views/index.html** 에 kakao login을 연결한다.
173 +
174 +```html
175 +<!-- 아래는 예시 -->
176 +<div>
177 + <div class="row">
178 + <div class="col-md-offset-1 col-md-5">
179 + <a href="/auth/facebook">
180 + <img src="/public/auth/assets/img/icons/facebook.png" />
181 + </a>
182 + <a href="/auth/twitter">
183 + <img src="/public/auth/assets/img/icons/twitter.png" />
184 + </a>
185 +
186 + <!-- kakao login -->
187 + <a href="/auth/kakao">
188 + <img
189 + src="https://developers.kakao.com/assets/img/about/logos/kakaolink/kakaolink_btn_medium.png"
190 + />
191 + </a>
192 + </div>
193 + </div>
194 + <div class="col-md-6">
195 + <div ui-view></div>
196 + </div>
197 +</div>
198 +```
199 +
200 +(8) grunt로 mean.io app 실행 후, 실제 로그인 연동 테스트를 해본다.
201 +
202 +## 기타
203 +
204 +passport-oauth 모듈과 passport-facebook 모듈을 참고함.
1 +"use strict";
2 +var __importDefault = (this && this.__importDefault) || function (mod) {
3 + return (mod && mod.__esModule) ? mod : { "default": mod };
4 +};
5 +Object.defineProperty(exports, "__esModule", { value: true });
6 +var util_1 = require("util");
7 +var passport_oauth2_1 = __importDefault(require("passport-oauth2"));
8 +var DEFAULT_CLIENT_SECRET = 'kakao';
9 +var OAUTH_HOST = 'https://kauth.kakao.com';
10 +var USER_PROFILE_URL = 'https://kapi.kakao.com/v2/user/me';
11 +exports.buildOptions = function (options) {
12 + options.authorizationURL = OAUTH_HOST + "/oauth/authorize";
13 + options.tokenURL = OAUTH_HOST + "/oauth/token";
14 + if (!options.clientSecret) {
15 + options.clientSecret = DEFAULT_CLIENT_SECRET;
16 + }
17 + options.scopeSeparator = options.scopeSeparator || ',';
18 + options.customHeaders = options.customHeaders || {};
19 + if (!options.customHeaders['User-Agent']) {
20 + options.customHeaders['User-Agent'] = options.userAgent || 'passport-kakao';
21 + }
22 + return options;
23 +};
24 +/**
25 + * KaKaoStrategy 생성자 함수.<br/>
26 + * @param options.clientID 필수. kakao rest app key.
27 + * @param options.callbackURL 필수. 로그인 처리 후 호출할 URL
28 + * @param verify
29 + * @constructor
30 + */
31 +function Strategy(options, verify) {
32 + if (options === void 0) { options = {}; }
33 + passport_oauth2_1.default.call(this, exports.buildOptions(options), verify);
34 + this.name = 'kakao';
35 + this._userProfileURL = USER_PROFILE_URL;
36 +}
37 +/**
38 + * `OAuth2Stragegy`를 상속 받는다.
39 + */
40 +util_1.inherits(Strategy, passport_oauth2_1.default);
41 +/**
42 + * kakao 사용자 정보를 얻는다.<br/>
43 + * 사용자 정보를 성공적으로 조회하면 아래의 object가 done 콜백함수 호출과 함꼐 넘어간다.
44 + *
45 + * - `provider` kakao 고정
46 + * - `id` kakao user id number
47 + * - `username` 사용자의 kakao nickname
48 + * - `_raw` json string 원문
49 + * _ `_json` json 원 데이터
50 + *
51 + * @param {String} accessToken
52 + * @param {Function} done
53 + */
54 +Strategy.prototype.userProfile = function (accessToken, done) {
55 + this._oauth2.get(this._userProfileURL, accessToken, function (err, body) {
56 + if (err) {
57 + return done(err);
58 + }
59 + try {
60 + var json = JSON.parse(body);
61 + // 카카오톡이나 카카오스토리에 연동한 적이 없는 계정의 경우
62 + // properties가 비어있다고 한다. 없을 경우의 처리
63 + var properties = json.properties || {
64 + nickname: '미연동 계정',
65 + };
66 + var profile = {
67 + provider: 'kakao',
68 + id: json.id,
69 + username: properties.nickname,
70 + displayName: properties.nickname,
71 + _raw: body,
72 + _json: json,
73 + };
74 + return done(null, profile);
75 + }
76 + catch (e) {
77 + return done(e);
78 + }
79 + });
80 +};
81 +exports.default = Strategy;
1 +"use strict";
2 +var __importDefault = (this && this.__importDefault) || function (mod) {
3 + return (mod && mod.__esModule) ? mod : { "default": mod };
4 +};
5 +Object.defineProperty(exports, "__esModule", { value: true });
6 +var Strategy_1 = __importDefault(require("./Strategy"));
7 +exports.Strategy = Strategy_1.default;
8 +exports.default = Strategy_1.default;
1 +"use strict";
2 +var __importDefault = (this && this.__importDefault) || function (mod) {
3 + return (mod && mod.__esModule) ? mod : { "default": mod };
4 +};
5 +Object.defineProperty(exports, "__esModule", { value: true });
6 +var util_1 = require("util");
7 +var passport_oauth2_1 = __importDefault(require("passport-oauth2"));
8 +var DEFAULT_CLIENT_SECRET = 'kakao';
9 +var OAUTH_HOST = 'https://kauth.kakao.com';
10 +var USER_PROFILE_URL = 'https://kapi.kakao.com/v2/user/me';
11 +exports.buildOptions = function (options) {
12 + options.authorizationURL = OAUTH_HOST + "/oauth/authorize";
13 + options.tokenURL = OAUTH_HOST + "/oauth/token";
14 + if (!options.clientSecret) {
15 + options.clientSecret = DEFAULT_CLIENT_SECRET;
16 + }
17 + options.scopeSeparator = options.scopeSeparator || ',';
18 + options.customHeaders = options.customHeaders || {};
19 + if (!options.customHeaders['User-Agent']) {
20 + options.customHeaders['User-Agent'] = options.userAgent || 'passport-kakao';
21 + }
22 + return options;
23 +};
24 +/**
25 + * KaKaoStrategy 생성자 함수.<br/>
26 + * @param options.clientID 필수. kakao rest app key.
27 + * @param options.callbackURL 필수. 로그인 처리 후 호출할 URL
28 + * @param verify
29 + * @constructor
30 + */
31 +function Strategy(options, verify) {
32 + if (options === void 0) { options = {}; }
33 + passport_oauth2_1.default.call(this, exports.buildOptions(options), verify);
34 + this.name = 'kakao';
35 + this._userProfileURL = USER_PROFILE_URL;
36 +}
37 +/**
38 + * `OAuth2Stragegy`를 상속 받는다.
39 + */
40 +util_1.inherits(Strategy, passport_oauth2_1.default);
41 +/**
42 + * kakao 사용자 정보를 얻는다.<br/>
43 + * 사용자 정보를 성공적으로 조회하면 아래의 object가 done 콜백함수 호출과 함꼐 넘어간다.
44 + *
45 + * - `provider` kakao 고정
46 + * - `id` kakao user id number
47 + * - `username` 사용자의 kakao nickname
48 + * - `_raw` json string 원문
49 + * _ `_json` json 원 데이터
50 + *
51 + * @param {String} accessToken
52 + * @param {Function} done
53 + */
54 +Strategy.prototype.userProfile = function (accessToken, done) {
55 + this._oauth2.get(this._userProfileURL, accessToken, function (err, body) {
56 + if (err) {
57 + return done(err);
58 + }
59 + try {
60 + var json = JSON.parse(body);
61 + // 카카오톡이나 카카오스토리에 연동한 적이 없는 계정의 경우
62 + // properties가 비어있다고 한다. 없을 경우의 처리
63 + var properties = json.properties || {
64 + nickname: '미연동 계정',
65 + };
66 + var profile = {
67 + provider: 'kakao',
68 + id: json.id,
69 + username: properties.nickname,
70 + displayName: properties.nickname,
71 + _raw: body,
72 + _json: json,
73 + };
74 + return done(null, profile);
75 + }
76 + catch (e) {
77 + return done(e);
78 + }
79 + });
80 +};
81 +exports.default = Strategy;
1 +"use strict";
2 +var __importDefault = (this && this.__importDefault) || function (mod) {
3 + return (mod && mod.__esModule) ? mod : { "default": mod };
4 +};
5 +Object.defineProperty(exports, "__esModule", { value: true });
6 +var Strategy_1 = __importDefault(require("./Strategy"));
7 +exports.Strategy = Strategy_1.default;
8 +exports.default = Strategy_1.default;
1 +"use strict";
2 +Object.defineProperty(exports, "__esModule", { value: true });
1 +"use strict";
2 +Object.defineProperty(exports, "__esModule", { value: true });
3 +describe('passport-kakao', function () {
4 + it('passport-kakao 객체가 제대로 생성이 되어 있어야 한다.', function () {
5 + var Strategy = require('../lib/passport-kakao');
6 + expect(Strategy).not.toBeNull();
7 + });
8 +});
1 +"use strict";
2 +var __importStar = (this && this.__importStar) || function (mod) {
3 + if (mod && mod.__esModule) return mod;
4 + var result = {};
5 + if (mod != null) for (var k in mod) if (Object.hasOwnProperty.call(mod, k)) result[k] = mod[k];
6 + result["default"] = mod;
7 + return result;
8 +};
9 +Object.defineProperty(exports, "__esModule", { value: true });
10 +var chai_1 = require("chai");
11 +var Strategy_1 = __importStar(require("../src/Strategy"));
12 +describe('passport-kakao', function () {
13 + it('passport-kakao 객체가 제대로 생성이 되어 있어야 한다.', function () {
14 + chai_1.expect(Strategy_1.default).to.not.equals(null);
15 + });
16 + it('Strategy option의 clientSecret 값이 없을 경우 default 값이 설정되어야 한다.', function () {
17 + var options = Strategy_1.buildOptions({});
18 + chai_1.expect(options).to.not.equals(null);
19 + chai_1.expect(options.clientSecret).to.be.equals('kakao');
20 + chai_1.expect(options.scopeSeparator).to.be.equals(',');
21 + chai_1.expect(options.customHeaders['User-Agent']).to.be.equals('passport-kakao');
22 + });
23 + it('Strategy option의 User-Agent값이 있을 경우 customHeaders의 User-Agent가 해당 값으로 설정되어야 한다.', function () {
24 + var options = Strategy_1.buildOptions({
25 + customHeaders: {
26 + 'User-Agent': 'HELLO ROTO',
27 + },
28 + });
29 + chai_1.expect(options.customHeaders['User-Agent']).to.be.equals('HELLO ROTO');
30 + });
31 +});
1 +"use strict";
2 +Object.defineProperty(exports, "__esModule", { value: true });
1 +(The MIT License)
2 +
3 +Copyright (c) 2011-2014 Jared Hanson
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 +# passport-oauth2
2 +
3 +[![Build](https://travis-ci.org/jaredhanson/passport-oauth2.png)](https://travis-ci.org/jaredhanson/passport-oauth2)
4 +[![Coverage](https://coveralls.io/repos/jaredhanson/passport-oauth2/badge.png)](https://coveralls.io/r/jaredhanson/passport-oauth2)
5 +[![Quality](https://codeclimate.com/github/jaredhanson/passport-oauth2.png)](https://codeclimate.com/github/jaredhanson/passport-oauth2)
6 +[![Dependencies](https://david-dm.org/jaredhanson/passport-oauth2.png)](https://david-dm.org/jaredhanson/passport-oauth2)
7 +[![Tips](http://img.shields.io/gittip/jaredhanson.png)](https://www.gittip.com/jaredhanson/)
8 +
9 +General-purpose OAuth 2.0 authentication strategy for [Passport](http://passportjs.org/).
10 +
11 +This module lets you authenticate using OAuth 2.0 in your Node.js applications.
12 +By plugging into Passport, OAuth 2.0 authentication can be easily and
13 +unobtrusively integrated into any application or framework that supports
14 +[Connect](http://www.senchalabs.org/connect/)-style middleware, including
15 +[Express](http://expressjs.com/).
16 +
17 +Note that this strategy provides generic OAuth 2.0 support. In many cases, a
18 +provider-specific strategy can be used instead, which cuts down on unnecessary
19 +configuration, and accommodates any provider-specific quirks. See the
20 +[list](https://github.com/jaredhanson/passport/wiki/Strategies) for supported
21 +providers.
22 +
23 +Developers who need to implement authentication against an OAuth 2.0 provider
24 +that is not already supported are encouraged to sub-class this strategy. If you
25 +choose to open source the new provider-specific strategy, please add it to the
26 +list so other people can find it.
27 +
28 +## Install
29 +
30 + $ npm install passport-oauth2
31 +
32 +## Usage
33 +
34 +#### Configure Strategy
35 +
36 +The OAuth 2.0 authentication strategy authenticates users using a third-party
37 +account and OAuth 2.0 tokens. The provider's OAuth 2.0 endpoints, as well as
38 +the client identifer and secret, are specified as options. The strategy
39 +requires a `verify` callback, which receives an access token and profile,
40 +and calls `done` providing a user.
41 +
42 + passport.use(new OAuth2Strategy({
43 + authorizationURL: 'https://www.example.com/oauth2/authorize',
44 + tokenURL: 'https://www.example.com/oauth2/token',
45 + clientID: EXAMPLE_CLIENT_ID,
46 + clientSecret: EXAMPLE_CLIENT_SECRET,
47 + callbackURL: "http://localhost:3000/auth/example/callback"
48 + },
49 + function(accessToken, refreshToken, profile, done) {
50 + User.findOrCreate({ exampleId: profile.id }, function (err, user) {
51 + return done(err, user);
52 + });
53 + }
54 + ));
55 +
56 +#### Authenticate Requests
57 +
58 +Use `passport.authenticate()`, specifying the `'oauth2'` strategy, to
59 +authenticate requests.
60 +
61 +For example, as route middleware in an [Express](http://expressjs.com/)
62 +application:
63 +
64 + app.get('/auth/example',
65 + passport.authenticate('oauth2'));
66 +
67 + app.get('/auth/example/callback',
68 + passport.authenticate('oauth2', { failureRedirect: '/login' }),
69 + function(req, res) {
70 + // Successful authentication, redirect home.
71 + res.redirect('/');
72 + });
73 +
74 +## Related Modules
75 +
76 +- [passport-oauth1](https://github.com/jaredhanson/passport-oauth1) — OAuth 1.0 authentication strategy
77 +- [passport-http-bearer](https://github.com/jaredhanson/passport-http-bearer) — Bearer token authentication strategy for APIs
78 +- [OAuth2orize](https://github.com/jaredhanson/oauth2orize) — OAuth 2.0 authorization server toolkit
79 +
80 +## Tests
81 +
82 + $ npm install
83 + $ npm test
84 +
85 +## Credits
86 +
87 + - [Jared Hanson](http://github.com/jaredhanson)
88 +
89 +## License
90 +
91 +[The MIT License](http://opensource.org/licenses/MIT)
92 +
93 +Copyright (c) 2011-2014 Jared Hanson <[http://jaredhanson.net/](http://jaredhanson.net/)>
1 +/**
2 + * `AuthorizationError` error.
3 + *
4 + * AuthorizationError represents an error in response to an authorization
5 + * request. For details, refer to RFC 6749, section 4.1.2.1.
6 + *
7 + * References:
8 + * - [The OAuth 2.0 Authorization Framework](http://tools.ietf.org/html/rfc6749)
9 + *
10 + * @constructor
11 + * @param {String} [message]
12 + * @param {String} [code]
13 + * @param {String} [uri]
14 + * @param {Number} [status]
15 + * @api public
16 + */
17 +function AuthorizationError(message, code, uri, status) {
18 + if (!status) {
19 + switch (code) {
20 + case 'access_denied': status = 403; break;
21 + case 'server_error': status = 502; break;
22 + case 'temporarily_unavailable': status = 503; break;
23 + }
24 + }
25 +
26 + Error.call(this);
27 + Error.captureStackTrace(this, arguments.callee);
28 + this.name = 'AuthorizationError';
29 + this.message = message;
30 + this.code = code || 'server_error';
31 + this.uri = uri;
32 + this.status = status || 500;
33 +}
34 +
35 +/**
36 + * Inherit from `Error`.
37 + */
38 +AuthorizationError.prototype.__proto__ = Error.prototype;
39 +
40 +
41 +/**
42 + * Expose `AuthorizationError`.
43 + */
44 +module.exports = AuthorizationError;
1 +/**
2 + * `InternalOAuthError` error.
3 + *
4 + * InternalOAuthError wraps errors generated by node-oauth. By wrapping these
5 + * objects, error messages can be formatted in a manner that aids in debugging
6 + * OAuth issues.
7 + *
8 + * @constructor
9 + * @param {String} [message]
10 + * @param {Object|Error} [err]
11 + * @api public
12 + */
13 +function InternalOAuthError(message, err) {
14 + Error.call(this);
15 + Error.captureStackTrace(this, arguments.callee);
16 + this.name = 'InternalOAuthError';
17 + this.message = message;
18 + this.oauthError = err;
19 +}
20 +
21 +/**
22 + * Inherit from `Error`.
23 + */
24 +InternalOAuthError.prototype.__proto__ = Error.prototype;
25 +
26 +/**
27 + * Returns a string representing the error.
28 + *
29 + * @return {String}
30 + * @api public
31 + */
32 +InternalOAuthError.prototype.toString = function() {
33 + var m = this.name;
34 + if (this.message) { m += ': ' + this.message; }
35 + if (this.oauthError) {
36 + if (this.oauthError instanceof Error) {
37 + m = this.oauthError.toString();
38 + } else if (this.oauthError.statusCode && this.oauthError.data) {
39 + m += ' (status: ' + this.oauthError.statusCode + ' data: ' + this.oauthError.data + ')';
40 + }
41 + }
42 + return m;
43 +};
44 +
45 +
46 +/**
47 + * Expose `InternalOAuthError`.
48 + */
49 +module.exports = InternalOAuthError;
1 +/**
2 + * `TokenError` error.
3 + *
4 + * TokenError represents an error received from a token endpoint. For details,
5 + * refer to RFC 6749, section 5.2.
6 + *
7 + * References:
8 + * - [The OAuth 2.0 Authorization Framework](http://tools.ietf.org/html/rfc6749)
9 + *
10 + * @constructor
11 + * @param {String} [message]
12 + * @param {String} [code]
13 + * @param {String} [uri]
14 + * @param {Number} [status]
15 + * @api public
16 + */
17 +function TokenError(message, code, uri, status) {
18 + Error.call(this);
19 + Error.captureStackTrace(this, arguments.callee);
20 + this.name = 'TokenError';
21 + this.message = message;
22 + this.code = code || 'invalid_request';
23 + this.uri = uri;
24 + this.status = status || 500;
25 +}
26 +
27 +/**
28 + * Inherit from `Error`.
29 + */
30 +TokenError.prototype.__proto__ = Error.prototype;
31 +
32 +
33 +/**
34 + * Expose `TokenError`.
35 + */
36 +module.exports = TokenError;
1 +/**
2 + * Module dependencies.
3 + */
4 +var Strategy = require('./strategy')
5 + , AuthorizationError = require('./errors/authorizationerror')
6 + , TokenError = require('./errors/tokenerror')
7 + , InternalOAuthError = require('./errors/internaloautherror');
8 +
9 +
10 +/**
11 + * Expose `Strategy` directly from package.
12 + */
13 +exports = module.exports = Strategy;
14 +
15 +/**
16 + * Export constructors.
17 + */
18 +exports.Strategy = Strategy;
19 +
20 +/**
21 + * Export errors.
22 + */
23 +exports.AuthorizationError = AuthorizationError;
24 +exports.TokenError = TokenError;
25 +exports.InternalOAuthError = InternalOAuthError;
1 +/**
2 + * Reconstructs the original URL of the request.
3 + *
4 + * This function builds a URL that corresponds the original URL requested by the
5 + * client, including the protocol (http or https) and host.
6 + *
7 + * If the request passed through any proxies that terminate SSL, the
8 + * `X-Forwarded-Proto` header is used to detect if the request was encrypted to
9 + * the proxy, assuming that the proxy has been flagged as trusted.
10 + *
11 + * @param {http.IncomingMessage} req
12 + * @param {Object} [options]
13 + * @return {String}
14 + * @api private
15 + */
16 +exports.originalURL = function(req, options) {
17 + options = options || {};
18 + var app = req.app;
19 + if (app && app.get && app.get('trust proxy')) {
20 + options.proxy = true;
21 + }
22 + var trustProxy = options.proxy;
23 +
24 + var proto = (req.headers['x-forwarded-proto'] || '').toLowerCase()
25 + , tls = req.connection.encrypted || (trustProxy && 'https' == proto.split(/\s*,\s*/)[0])
26 + , host = (trustProxy && req.headers['x-forwarded-host']) || req.headers.host
27 + , protocol = tls ? 'https' : 'http'
28 + , path = req.url || '';
29 + return protocol + '://' + host + path;
30 +};
1 +{
2 + "_from": "passport-oauth2@~1.1.2",
3 + "_id": "passport-oauth2@1.1.2",
4 + "_inBundle": false,
5 + "_integrity": "sha1-vXFjsbYJA3GGjcTvb58uHkzEuUg=",
6 + "_location": "/passport-kakao/passport-oauth2",
7 + "_phantomChildren": {},
8 + "_requested": {
9 + "type": "range",
10 + "registry": true,
11 + "raw": "passport-oauth2@~1.1.2",
12 + "name": "passport-oauth2",
13 + "escapedName": "passport-oauth2",
14 + "rawSpec": "~1.1.2",
15 + "saveSpec": null,
16 + "fetchSpec": "~1.1.2"
17 + },
18 + "_requiredBy": [
19 + "/passport-kakao"
20 + ],
21 + "_resolved": "https://registry.npmjs.org/passport-oauth2/-/passport-oauth2-1.1.2.tgz",
22 + "_shasum": "bd7163b1b6090371868dc4ef6f9f2e1e4cc4b948",
23 + "_spec": "passport-oauth2@~1.1.2",
24 + "_where": "C:\\Users\\LG\\Desktop\\4-1\\Reminder-Talk\\node_modules\\passport-kakao",
25 + "author": {
26 + "name": "Jared Hanson",
27 + "email": "jaredhanson@gmail.com",
28 + "url": "http://www.jaredhanson.net/"
29 + },
30 + "bugs": {
31 + "url": "http://github.com/jaredhanson/passport-oauth2/issues"
32 + },
33 + "bundleDependencies": false,
34 + "dependencies": {
35 + "oauth": "0.9.x",
36 + "passport-strategy": "1.x.x",
37 + "uid2": "0.0.x"
38 + },
39 + "deprecated": false,
40 + "description": "OAuth 2.0 authentication strategy for Passport.",
41 + "devDependencies": {
42 + "chai": "1.x.x",
43 + "chai-passport-strategy": "0.2.x",
44 + "mocha": "1.x.x"
45 + },
46 + "engines": {
47 + "node": ">= 0.4.0"
48 + },
49 + "homepage": "https://github.com/jaredhanson/passport-oauth2#readme",
50 + "keywords": [
51 + "passport",
52 + "auth",
53 + "authn",
54 + "authentication",
55 + "authz",
56 + "authorization",
57 + "oauth",
58 + "oauth2"
59 + ],
60 + "licenses": [
61 + {
62 + "type": "MIT",
63 + "url": "http://www.opensource.org/licenses/MIT"
64 + }
65 + ],
66 + "main": "./lib",
67 + "name": "passport-oauth2",
68 + "repository": {
69 + "type": "git",
70 + "url": "git://github.com/jaredhanson/passport-oauth2.git"
71 + },
72 + "scripts": {
73 + "test": "mocha --reporter spec --require test/bootstrap/node test/*.test.js test/**/*.test.js"
74 + },
75 + "version": "1.1.2"
76 +}
1 +node_modules/
2 +npm-debug.log
...\ No newline at end of file ...\ No newline at end of file
1 +Copyright (c) 2010 Charlie Robbins.
2 +
3 +Permission is hereby granted, free of charge, to any person obtaining a copy
4 +of this software and associated documentation files (the "Software"), to deal
5 +in the Software without restriction, including without limitation the rights
6 +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
7 +copies of the Software, and to permit persons to whom the Software is
8 +furnished to do so, subject to the following conditions:
9 +
10 +The above copyright notice and this permission notice shall be included in
11 +all copies or substantial portions of the Software.
12 +
13 +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14 +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15 +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
16 +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
17 +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
18 +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
19 +THE SOFTWARE.
...\ No newline at end of file ...\ No newline at end of file
1 +# node-pkginfo
2 +
3 +An easy way to expose properties on a module from a package.json
4 +
5 +## Installation
6 +
7 +### Installing npm (node package manager)
8 +```
9 + curl http://npmjs.org/install.sh | sh
10 +```
11 +
12 +### Installing pkginfo
13 +```
14 + [sudo] npm install pkginfo
15 +```
16 +
17 +## Motivation
18 +How often when writing node.js modules have you written the following line(s) of code?
19 +
20 +* Hard code your version string into your code
21 +
22 +``` js
23 + exports.version = '0.1.0';
24 +```
25 +
26 +* Programmatically expose the version from the package.json
27 +
28 +``` js
29 + exports.version = require('/path/to/package.json').version;
30 +```
31 +
32 +In other words, how often have you wanted to expose basic information from your package.json onto your module programmatically? **WELL NOW YOU CAN!**
33 +
34 +## Usage
35 +
36 +Using `pkginfo` is idiot-proof, just require and invoke it.
37 +
38 +``` js
39 + var pkginfo = require('pkginfo')(module);
40 +
41 + console.dir(module.exports);
42 +```
43 +
44 +By invoking the `pkginfo` module all of the properties in your `package.json` file will be automatically exposed on the callee module (i.e. the parent module of `pkginfo`).
45 +
46 +Here's a sample of the output:
47 +
48 +```
49 + { name: 'simple-app',
50 + description: 'A test fixture for pkginfo',
51 + version: '0.1.0',
52 + author: 'Charlie Robbins <charlie.robbins@gmail.com>',
53 + keywords: [ 'test', 'fixture' ],
54 + main: './index.js',
55 + scripts: { test: 'vows test/*-test.js --spec' },
56 + engines: { node: '>= 0.4.0' } }
57 +```
58 +
59 +### Expose specific properties
60 +If you don't want to expose **all** properties on from your `package.json` on your module then simple pass those properties to the `pkginfo` function:
61 +
62 +``` js
63 + var pkginfo = require('pkginfo')(module, 'version', 'author');
64 +
65 + console.dir(module.exports);
66 +```
67 +
68 +```
69 + { version: '0.1.0',
70 + author: 'Charlie Robbins <charlie.robbins@gmail.com>' }
71 +```
72 +
73 +If you're looking for further usage see the [examples][0] included in this repository.
74 +
75 +## Run Tests
76 +Tests are written in [vows][1] and give complete coverage of all APIs.
77 +
78 +```
79 + vows test/*-test.js --spec
80 +```
81 +
82 +[0]: https://github.com/indexzero/node-pkginfo/tree/master/examples
83 +[1]: http://vowsjs.org
84 +
85 +#### Author: [Charlie Robbins](http://nodejitsu.com)
86 +#### License: MIT
1 +/*--------------------- Layout and Typography ----------------------------*/
2 +body {
3 + font-family: 'Palatino Linotype', 'Book Antiqua', Palatino, FreeSerif, serif;
4 + font-size: 15px;
5 + line-height: 22px;
6 + color: #252519;
7 + margin: 0; padding: 0;
8 +}
9 +a {
10 + color: #261a3b;
11 +}
12 + a:visited {
13 + color: #261a3b;
14 + }
15 +p {
16 + margin: 0 0 15px 0;
17 +}
18 +h4, h5, h6 {
19 + color: #333;
20 + margin: 6px 0 6px 0;
21 + font-size: 13px;
22 +}
23 + h2, h3 {
24 + margin-bottom: 0;
25 + color: #000;
26 + }
27 + h1 {
28 + margin-top: 40px;
29 + margin-bottom: 15px;
30 + color: #000;
31 + }
32 +#container {
33 + position: relative;
34 +}
35 +#background {
36 + position: fixed;
37 + top: 0; left: 525px; right: 0; bottom: 0;
38 + background: #f5f5ff;
39 + border-left: 1px solid #e5e5ee;
40 + z-index: -1;
41 +}
42 +#jump_to, #jump_page {
43 + background: white;
44 + -webkit-box-shadow: 0 0 25px #777; -moz-box-shadow: 0 0 25px #777;
45 + -webkit-border-bottom-left-radius: 5px; -moz-border-radius-bottomleft: 5px;
46 + font: 10px Arial;
47 + text-transform: uppercase;
48 + cursor: pointer;
49 + text-align: right;
50 +}
51 +#jump_to, #jump_wrapper {
52 + position: fixed;
53 + right: 0; top: 0;
54 + padding: 5px 10px;
55 +}
56 + #jump_wrapper {
57 + padding: 0;
58 + display: none;
59 + }
60 + #jump_to:hover #jump_wrapper {
61 + display: block;
62 + }
63 + #jump_page {
64 + padding: 5px 0 3px;
65 + margin: 0 0 25px 25px;
66 + }
67 + #jump_page .source {
68 + display: block;
69 + padding: 5px 10px;
70 + text-decoration: none;
71 + border-top: 1px solid #eee;
72 + }
73 + #jump_page .source:hover {
74 + background: #f5f5ff;
75 + }
76 + #jump_page .source:first-child {
77 + }
78 +table td {
79 + border: 0;
80 + outline: 0;
81 +}
82 + td.docs, th.docs {
83 + max-width: 450px;
84 + min-width: 450px;
85 + min-height: 5px;
86 + padding: 10px 25px 1px 50px;
87 + overflow-x: hidden;
88 + vertical-align: top;
89 + text-align: left;
90 + }
91 + .docs pre {
92 + margin: 15px 0 15px;
93 + padding-left: 15px;
94 + }
95 + .docs p tt, .docs p code {
96 + background: #f8f8ff;
97 + border: 1px solid #dedede;
98 + font-size: 12px;
99 + padding: 0 0.2em;
100 + }
101 + .pilwrap {
102 + position: relative;
103 + }
104 + .pilcrow {
105 + font: 12px Arial;
106 + text-decoration: none;
107 + color: #454545;
108 + position: absolute;
109 + top: 3px; left: -20px;
110 + padding: 1px 2px;
111 + opacity: 0;
112 + -webkit-transition: opacity 0.2s linear;
113 + }
114 + td.docs:hover .pilcrow {
115 + opacity: 1;
116 + }
117 + td.code, th.code {
118 + padding: 14px 15px 16px 25px;
119 + width: 100%;
120 + vertical-align: top;
121 + background: #f5f5ff;
122 + border-left: 1px solid #e5e5ee;
123 + }
124 + pre, tt, code {
125 + font-size: 12px; line-height: 18px;
126 + font-family: Menlo, Monaco, Consolas, "Lucida Console", monospace;
127 + margin: 0; padding: 0;
128 + }
129 +
130 +
131 +/*---------------------- Syntax Highlighting -----------------------------*/
132 +td.linenos { background-color: #f0f0f0; padding-right: 10px; }
133 +span.lineno { background-color: #f0f0f0; padding: 0 5px 0 5px; }
134 +body .hll { background-color: #ffffcc }
135 +body .c { color: #408080; font-style: italic } /* Comment */
136 +body .err { border: 1px solid #FF0000 } /* Error */
137 +body .k { color: #954121 } /* Keyword */
138 +body .o { color: #666666 } /* Operator */
139 +body .cm { color: #408080; font-style: italic } /* Comment.Multiline */
140 +body .cp { color: #BC7A00 } /* Comment.Preproc */
141 +body .c1 { color: #408080; font-style: italic } /* Comment.Single */
142 +body .cs { color: #408080; font-style: italic } /* Comment.Special */
143 +body .gd { color: #A00000 } /* Generic.Deleted */
144 +body .ge { font-style: italic } /* Generic.Emph */
145 +body .gr { color: #FF0000 } /* Generic.Error */
146 +body .gh { color: #000080; font-weight: bold } /* Generic.Heading */
147 +body .gi { color: #00A000 } /* Generic.Inserted */
148 +body .go { color: #808080 } /* Generic.Output */
149 +body .gp { color: #000080; font-weight: bold } /* Generic.Prompt */
150 +body .gs { font-weight: bold } /* Generic.Strong */
151 +body .gu { color: #800080; font-weight: bold } /* Generic.Subheading */
152 +body .gt { color: #0040D0 } /* Generic.Traceback */
153 +body .kc { color: #954121 } /* Keyword.Constant */
154 +body .kd { color: #954121; font-weight: bold } /* Keyword.Declaration */
155 +body .kn { color: #954121; font-weight: bold } /* Keyword.Namespace */
156 +body .kp { color: #954121 } /* Keyword.Pseudo */
157 +body .kr { color: #954121; font-weight: bold } /* Keyword.Reserved */
158 +body .kt { color: #B00040 } /* Keyword.Type */
159 +body .m { color: #666666 } /* Literal.Number */
160 +body .s { color: #219161 } /* Literal.String */
161 +body .na { color: #7D9029 } /* Name.Attribute */
162 +body .nb { color: #954121 } /* Name.Builtin */
163 +body .nc { color: #0000FF; font-weight: bold } /* Name.Class */
164 +body .no { color: #880000 } /* Name.Constant */
165 +body .nd { color: #AA22FF } /* Name.Decorator */
166 +body .ni { color: #999999; font-weight: bold } /* Name.Entity */
167 +body .ne { color: #D2413A; font-weight: bold } /* Name.Exception */
168 +body .nf { color: #0000FF } /* Name.Function */
169 +body .nl { color: #A0A000 } /* Name.Label */
170 +body .nn { color: #0000FF; font-weight: bold } /* Name.Namespace */
171 +body .nt { color: #954121; font-weight: bold } /* Name.Tag */
172 +body .nv { color: #19469D } /* Name.Variable */
173 +body .ow { color: #AA22FF; font-weight: bold } /* Operator.Word */
174 +body .w { color: #bbbbbb } /* Text.Whitespace */
175 +body .mf { color: #666666 } /* Literal.Number.Float */
176 +body .mh { color: #666666 } /* Literal.Number.Hex */
177 +body .mi { color: #666666 } /* Literal.Number.Integer */
178 +body .mo { color: #666666 } /* Literal.Number.Oct */
179 +body .sb { color: #219161 } /* Literal.String.Backtick */
180 +body .sc { color: #219161 } /* Literal.String.Char */
181 +body .sd { color: #219161; font-style: italic } /* Literal.String.Doc */
182 +body .s2 { color: #219161 } /* Literal.String.Double */
183 +body .se { color: #BB6622; font-weight: bold } /* Literal.String.Escape */
184 +body .sh { color: #219161 } /* Literal.String.Heredoc */
185 +body .si { color: #BB6688; font-weight: bold } /* Literal.String.Interpol */
186 +body .sx { color: #954121 } /* Literal.String.Other */
187 +body .sr { color: #BB6688 } /* Literal.String.Regex */
188 +body .s1 { color: #219161 } /* Literal.String.Single */
189 +body .ss { color: #19469D } /* Literal.String.Symbol */
190 +body .bp { color: #954121 } /* Name.Builtin.Pseudo */
191 +body .vc { color: #19469D } /* Name.Variable.Class */
192 +body .vg { color: #19469D } /* Name.Variable.Global */
193 +body .vi { color: #19469D } /* Name.Variable.Instance */
194 +body .il { color: #666666 } /* Literal.Number.Integer.Long */
...\ No newline at end of file ...\ No newline at end of file
1 +/*
2 + * all-properties.js: Sample of including all properties from a package.json file
3 + *
4 + * (C) 2011, Charlie Robbins
5 + *
6 + */
7 +
8 +var util = require('util'),
9 + pkginfo = require('../lib/pkginfo')(module);
10 +
11 +exports.someFunction = function () {
12 + console.log('some of your custom logic here');
13 +};
14 +
15 +console.log('Inspecting module:');
16 +console.dir(module.exports);
17 +
18 +console.log('\nAll exports exposed:');
19 +console.error(Object.keys(module.exports));
...\ No newline at end of file ...\ No newline at end of file
1 +/*
2 + * array-argument.js: Sample of including specific properties from a package.json file
3 + * using Array argument syntax.
4 + *
5 + * (C) 2011, Charlie Robbins
6 + *
7 + */
8 +
9 +var util = require('util'),
10 + pkginfo = require('../lib/pkginfo')(module, ['version', 'author']);
11 +
12 +exports.someFunction = function () {
13 + console.log('some of your custom logic here');
14 +};
15 +
16 +console.log('Inspecting module:');
17 +console.dir(module.exports);
18 +
19 +console.log('\nAll exports exposed:');
20 +console.error(Object.keys(module.exports));
...\ No newline at end of file ...\ No newline at end of file
1 +/*
2 + * multiple-properties.js: Sample of including multiple properties from a package.json file
3 + *
4 + * (C) 2011, Charlie Robbins
5 + *
6 + */
7 +
8 +var util = require('util'),
9 + pkginfo = require('../lib/pkginfo')(module, 'version', 'author');
10 +
11 +exports.someFunction = function () {
12 + console.log('some of your custom logic here');
13 +};
14 +
15 +console.log('Inspecting module:');
16 +console.dir(module.exports);
17 +
18 +console.log('\nAll exports exposed:');
19 +console.error(Object.keys(module.exports));
...\ No newline at end of file ...\ No newline at end of file
1 +/*
2 + * object-argument.js: Sample of including specific properties from a package.json file
3 + * using Object argument syntax.
4 + *
5 + * (C) 2011, Charlie Robbins
6 + *
7 + */
8 +
9 +var util = require('util'),
10 + pkginfo = require('../lib/pkginfo')(module, {
11 + include: ['version', 'author']
12 + });
13 +
14 +exports.someFunction = function () {
15 + console.log('some of your custom logic here');
16 +};
17 +
18 +console.log('Inspecting module:');
19 +console.dir(module.exports);
20 +
21 +console.log('\nAll exports exposed:');
22 +console.error(Object.keys(module.exports));
...\ No newline at end of file ...\ No newline at end of file
1 +{
2 + "name": "simple-app",
3 + "description": "A test fixture for pkginfo",
4 + "version": "0.1.0",
5 + "author": "Charlie Robbins <charlie.robbins@gmail.com>",
6 + "keywords": ["test", "fixture"],
7 + "main": "./index.js",
8 + "scripts": { "test": "vows test/*-test.js --spec" },
9 + "engines": { "node": ">= 0.4.0" }
10 +}
1 +/*
2 + * single-property.js: Sample of including a single specific properties from a package.json file
3 + *
4 + * (C) 2011, Charlie Robbins
5 + *
6 + */
7 +
8 +var util = require('util'),
9 + pkginfo = require('../lib/pkginfo')(module, 'version');
10 +
11 +exports.someFunction = function () {
12 + console.log('some of your custom logic here');
13 +};
14 +
15 +console.log('Inspecting module:');
16 +console.dir(module.exports);
17 +
18 +console.log('\nAll exports exposed:');
19 +console.error(Object.keys(module.exports));
...\ No newline at end of file ...\ No newline at end of file
1 +{
2 + "name": "simple-app-subdir",
3 + "description": "A test fixture for pkginfo",
4 + "version": "0.1.0",
5 + "author": "Charlie Robbins <charlie.robbins@gmail.com>",
6 + "keywords": ["test", "fixture"],
7 + "main": "./index.js",
8 + "scripts": { "test": "vows test/*-test.js --spec" },
9 + "engines": { "node": ">= 0.4.0" },
10 + "subdironly": "true"
11 +}
1 +/*
2 + * multiple-properties.js: Sample of including multiple properties from a package.json file
3 + *
4 + * (C) 2011, Charlie Robbins
5 + *
6 + */
7 +
8 +var util = require('util'),
9 + path = require('path'),
10 + pkginfo = require('../lib/pkginfo')(module, { dir: path.resolve(__dirname, 'subdir' )});
11 +
12 +exports.someFunction = function () {
13 + console.log('some of your custom logic here');
14 +};
15 +
16 +console.log('Inspecting module:');
17 +console.dir(module.exports);
18 +
19 +console.log('\nAll exports exposed:');
20 +console.error(Object.keys(module.exports));
...\ No newline at end of file ...\ No newline at end of file
1 +/*
2 + * pkginfo.js: Top-level include for the pkginfo module
3 + *
4 + * (C) 2011, Charlie Robbins
5 + *
6 + */
7 +
8 +var fs = require('fs'),
9 + path = require('path');
10 +
11 +//
12 +// ### function pkginfo ([options, 'property', 'property' ..])
13 +// #### @pmodule {Module} Parent module to read from.
14 +// #### @options {Object|Array|string} **Optional** Options used when exposing properties.
15 +// #### @arguments {string...} **Optional** Specified properties to expose.
16 +// Exposes properties from the package.json file for the parent module on
17 +// it's exports. Valid usage:
18 +//
19 +// `require('pkginfo')()`
20 +//
21 +// `require('pkginfo')('version', 'author');`
22 +//
23 +// `require('pkginfo')(['version', 'author']);`
24 +//
25 +// `require('pkginfo')({ include: ['version', 'author'] });`
26 +//
27 +var pkginfo = module.exports = function (pmodule, options) {
28 + var args = [].slice.call(arguments, 2).filter(function (arg) {
29 + return typeof arg === 'string';
30 + });
31 +
32 + //
33 + // **Parse variable arguments**
34 + //
35 + if (Array.isArray(options)) {
36 + //
37 + // If the options passed in is an Array assume that
38 + // it is the Array of properties to expose from the
39 + // on the package.json file on the parent module.
40 + //
41 + options = { include: options };
42 + }
43 + else if (typeof options === 'string') {
44 + //
45 + // Otherwise if the first argument is a string, then
46 + // assume that it is the first property to expose from
47 + // the package.json file on the parent module.
48 + //
49 + options = { include: [options] };
50 + }
51 +
52 + //
53 + // **Setup default options**
54 + //
55 + options = options || {};
56 +
57 + // ensure that includes have been defined
58 + options.include = options.include || [];
59 +
60 + if (args.length > 0) {
61 + //
62 + // If additional string arguments have been passed in
63 + // then add them to the properties to expose on the
64 + // parent module.
65 + //
66 + options.include = options.include.concat(args);
67 + }
68 +
69 + var pkg = pkginfo.read(pmodule, options.dir).package;
70 + Object.keys(pkg).forEach(function (key) {
71 + if (options.include.length > 0 && !~options.include.indexOf(key)) {
72 + return;
73 + }
74 +
75 + if (!pmodule.exports[key]) {
76 + pmodule.exports[key] = pkg[key];
77 + }
78 + });
79 +
80 + return pkginfo;
81 +};
82 +
83 +//
84 +// ### function find (dir)
85 +// #### @pmodule {Module} Parent module to read from.
86 +// #### @dir {string} **Optional** Directory to start search from.
87 +// Searches up the directory tree from `dir` until it finds a directory
88 +// which contains a `package.json` file.
89 +//
90 +pkginfo.find = function (pmodule, dir) {
91 + if (! dir) {
92 + dir = path.dirname(pmodule.filename);
93 + }
94 +
95 + var files = fs.readdirSync(dir);
96 +
97 + if (~files.indexOf('package.json')) {
98 + return path.join(dir, 'package.json');
99 + }
100 +
101 + if (dir === '/') {
102 + throw new Error('Could not find package.json up from: ' + dir);
103 + }
104 + else if (!dir || dir === '.') {
105 + throw new Error('Cannot find package.json from unspecified directory');
106 + }
107 +
108 + return pkginfo.find(pmodule, path.dirname(dir));
109 +};
110 +
111 +//
112 +// ### function read (pmodule, dir)
113 +// #### @pmodule {Module} Parent module to read from.
114 +// #### @dir {string} **Optional** Directory to start search from.
115 +// Searches up the directory tree from `dir` until it finds a directory
116 +// which contains a `package.json` file and returns the package information.
117 +//
118 +pkginfo.read = function (pmodule, dir) {
119 + dir = pkginfo.find(pmodule, dir);
120 +
121 + var data = fs.readFileSync(dir).toString();
122 +
123 + return {
124 + dir: dir,
125 + package: JSON.parse(data)
126 + };
127 +};
128 +
129 +//
130 +// Call `pkginfo` on this module and expose version.
131 +//
132 +pkginfo(module, {
133 + dir: __dirname,
134 + include: ['version'],
135 + target: pkginfo
136 +});
...\ No newline at end of file ...\ No newline at end of file
1 +{
2 + "_from": "pkginfo@~0.3.0",
3 + "_id": "pkginfo@0.3.1",
4 + "_inBundle": false,
5 + "_integrity": "sha1-Wyn2qB9wcXFC4J52W76rl7T4HiE=",
6 + "_location": "/passport-kakao/pkginfo",
7 + "_phantomChildren": {},
8 + "_requested": {
9 + "type": "range",
10 + "registry": true,
11 + "raw": "pkginfo@~0.3.0",
12 + "name": "pkginfo",
13 + "escapedName": "pkginfo",
14 + "rawSpec": "~0.3.0",
15 + "saveSpec": null,
16 + "fetchSpec": "~0.3.0"
17 + },
18 + "_requiredBy": [
19 + "/passport-kakao"
20 + ],
21 + "_resolved": "https://registry.npmjs.org/pkginfo/-/pkginfo-0.3.1.tgz",
22 + "_shasum": "5b29f6a81f70717142e09e765bbeab97b4f81e21",
23 + "_spec": "pkginfo@~0.3.0",
24 + "_where": "C:\\Users\\LG\\Desktop\\4-1\\Reminder-Talk\\node_modules\\passport-kakao",
25 + "author": {
26 + "name": "Charlie Robbins",
27 + "email": "charlie.robbins@gmail.com"
28 + },
29 + "bugs": {
30 + "url": "https://github.com/indexzero/node-pkginfo/issues"
31 + },
32 + "bundleDependencies": false,
33 + "deprecated": false,
34 + "description": "An easy way to expose properties on a module from a package.json",
35 + "devDependencies": {
36 + "vows": "0.7.x"
37 + },
38 + "engines": {
39 + "node": ">= 0.4.0"
40 + },
41 + "homepage": "https://github.com/indexzero/node-pkginfo#readme",
42 + "keywords": [
43 + "info",
44 + "tools",
45 + "package.json"
46 + ],
47 + "license": "MIT",
48 + "main": "./lib/pkginfo.js",
49 + "name": "pkginfo",
50 + "repository": {
51 + "type": "git",
52 + "url": "git+ssh://git@github.com/indexzero/node-pkginfo.git"
53 + },
54 + "scripts": {
55 + "test": "vows test/*-test.js --spec"
56 + },
57 + "version": "0.3.1"
58 +}
1 +/*
2 + * pkginfo-test.js: Tests for the pkginfo module.
3 + *
4 + * (C) 2011, Charlie Robbins
5 + *
6 + */
7 +
8 +var assert = require('assert'),
9 + exec = require('child_process').exec,
10 + fs = require('fs'),
11 + path = require('path'),
12 + vows = require('vows'),
13 + pkginfo = require('../lib/pkginfo');
14 +
15 +function assertProperties (source, target) {
16 + assert.lengthOf(source, target.length + 1);
17 + target.forEach(function (prop) {
18 + assert.isTrue(!!~source.indexOf(prop));
19 + });
20 +}
21 +
22 +function compareWithExample(targetPath) {
23 + var examplePaths = ['package.json'];
24 +
25 + if (targetPath) {
26 + examplePaths.unshift(targetPath);
27 + }
28 +
29 + return function(exposed) {
30 + var pkg = fs.readFileSync(path.join.apply(null, [__dirname, '..', 'examples'].concat(examplePaths))).toString(),
31 + keys = Object.keys(JSON.parse(pkg));
32 +
33 + assertProperties(exposed, keys);
34 + };
35 +}
36 +
37 +function testExposes (options) {
38 + return {
39 + topic: function () {
40 + exec('node ' + path.join(__dirname, '..', 'examples', options.script), this.callback);
41 + },
42 + "should expose that property correctly": function (err, stdout, stderr) {
43 + assert.isNull(err);
44 +
45 + var exposed = stderr.match(/'(\w+)'/ig).map(function (p) {
46 + return p.substring(1, p.length - 1);
47 + });
48 +
49 + return !options.assert
50 + ? assertProperties(exposed, options.properties)
51 + : options.assert(exposed);
52 + }
53 + }
54 +}
55 +
56 +vows.describe('pkginfo').addBatch({
57 + "When using the pkginfo module": {
58 + "and passed a single `string` argument": testExposes({
59 + script: 'single-property.js',
60 + properties: ['version']
61 + }),
62 + "and passed multiple `string` arguments": testExposes({
63 + script: 'multiple-properties.js',
64 + properties: ['version', 'author']
65 + }),
66 + "and passed an `object` argument": testExposes({
67 + script: 'object-argument.js',
68 + properties: ['version', 'author']
69 + }),
70 + "and passed an `array` argument": testExposes({
71 + script: 'array-argument.js',
72 + properties: ['version', 'author']
73 + }),
74 + "and read from a specified directory": testExposes({
75 + script: 'target-dir.js',
76 + assert: compareWithExample('subdir')
77 + }),
78 + "and passed no arguments": testExposes({
79 + script: 'all-properties.js',
80 + assert: compareWithExample()
81 + })
82 + }
83 +}).export(module);
1 +{
2 + "_from": "passport-kakao",
3 + "_id": "passport-kakao@1.0.0",
4 + "_inBundle": false,
5 + "_integrity": "sha512-rOR3+8g1bev/p9ChZLDKQan9oBmSSA2hmb7yQKdBOsjyF1mijx7fgR05pTWPz3g5r0kHZ2Y44sT2Ys6wJQq0xQ==",
6 + "_location": "/passport-kakao",
7 + "_phantomChildren": {
8 + "oauth": "0.9.15",
9 + "passport-strategy": "1.0.0",
10 + "uid2": "0.0.3"
11 + },
12 + "_requested": {
13 + "type": "tag",
14 + "registry": true,
15 + "raw": "passport-kakao",
16 + "name": "passport-kakao",
17 + "escapedName": "passport-kakao",
18 + "rawSpec": "",
19 + "saveSpec": null,
20 + "fetchSpec": "latest"
21 + },
22 + "_requiredBy": [
23 + "#USER",
24 + "/"
25 + ],
26 + "_resolved": "https://registry.npmjs.org/passport-kakao/-/passport-kakao-1.0.0.tgz",
27 + "_shasum": "11924fb3a5c9f174e3d9a6b8c75d729066ef388d",
28 + "_spec": "passport-kakao",
29 + "_where": "C:\\Users\\LG\\Desktop\\4-1\\Reminder-Talk",
30 + "author": {
31 + "name": "rotoshine@gmail.com"
32 + },
33 + "bugs": {
34 + "url": "https://github.com/rotoshine/passport-kakao/issues"
35 + },
36 + "bundleDependencies": false,
37 + "dependencies": {
38 + "passport-oauth2": "~1.1.2",
39 + "pkginfo": "~0.3.0"
40 + },
41 + "deprecated": false,
42 + "description": "kakao oauth2 login module",
43 + "devDependencies": {
44 + "@types/chai": "^4.2.3",
45 + "@types/mocha": "^5.2.7",
46 + "@types/node": "^12.7.11",
47 + "chai": "^4.2.0",
48 + "mocha": "^6.2.1",
49 + "ts-node": "^8.4.1",
50 + "tslint": "^5.20.0",
51 + "tslint-config-prettier": "^1.18.0",
52 + "typescript": "^3.6.3"
53 + },
54 + "homepage": "https://github.com/rotoshine/passport-kakao#readme",
55 + "keywords": [
56 + "passport",
57 + "kakao",
58 + "kakaotalk",
59 + "oauth2"
60 + ],
61 + "license": "MIT",
62 + "main": "./dist/passport-kakao",
63 + "name": "passport-kakao",
64 + "repository": {
65 + "type": "git",
66 + "url": "git://github.com/rotoshine/passport-kakao.git"
67 + },
68 + "scripts": {
69 + "build": "npx tsc",
70 + "lint": "tslint --project .",
71 + "test": "mocha -r node_modules/ts-node/register ./tests/**/*.spec.ts"
72 + },
73 + "version": "1.0.0"
74 +}
This diff is collapsed. Click to expand it.
1 +{
2 + "name": "passport-kakao-sample",
3 + "repository": {
4 + "type": "git",
5 + "url": "git://github.com/rotoshine/passport-kakao.git"
6 + },
7 + "dependencies": {
8 + "passport": ">= 0.0.0",
9 + "express": ">= 4.4.5"
10 + }
11 +}
1 +const passport = require('passport')
2 +const express = require('express')
3 +const KakaoStrategy = require('../dist/passport-kakao.js').Strategy
4 +
5 +const appKey = 'YOUR_APP_REST_API_KEY'
6 +const appSecret = 'YOUR_APP_CLIENT_SECRET_KEY'
7 +
8 +// passport 에 Kakao Oauth 추가
9 +passport.use(
10 + new KakaoStrategy(
11 + {
12 + clientID: appKey,
13 + clientSecret: appSecret,
14 + callbackURL: 'http://localhost:3000/oauth',
15 + },
16 + function(accessToken, refreshToken, params, profile, done) {
17 + // authorization 에 성공했을때의 액션
18 + console.log(`accessToken : ${accessToken}`)
19 + console.log(`사용자 profile: ${JSON.stringify(profile._json)}`)
20 +
21 + save(accessToken, refreshToken, profile)
22 + return done(null, profile._json)
23 + }
24 + )
25 +)
26 +passport.serializeUser(function(user, done) {
27 + done(null, user)
28 +})
29 +passport.deserializeUser(function(obj, done) {
30 + done(null, obj)
31 +})
32 +
33 +// express 앱 설정
34 +var app = express()
35 +app.use(passport.initialize())
36 +app.get('/login', passport.authenticate('kakao', { state: 'myStateValue' }))
37 +app.get('/oauth', passport.authenticate('kakao'), function(req, res) {
38 + // 로그인 시작시 state 값을 받을 수 있음
39 + res.send('state :' + req.query.state)
40 +})
41 +app.listen(3000)
42 +
43 +// 사용자 구현 부분
44 +function save() {
45 + //save 로직 구현
46 +}
1 +import { inherits } from 'util'
2 +import OAuth2Strategy from 'passport-oauth2'
3 +
4 +import { StrategyOptions, Profile } from './types/models'
5 +
6 +const DEFAULT_CLIENT_SECRET = 'kakao'
7 +const OAUTH_HOST = 'https://kauth.kakao.com'
8 +const USER_PROFILE_URL = 'https://kapi.kakao.com/v2/user/me'
9 +
10 +export const buildOptions = (options: StrategyOptions) => {
11 + options.authorizationURL = `${OAUTH_HOST}/oauth/authorize`
12 + options.tokenURL = `${OAUTH_HOST}/oauth/token`
13 +
14 + if (!options.clientSecret) {
15 + options.clientSecret = DEFAULT_CLIENT_SECRET
16 + }
17 +
18 + options.scopeSeparator = options.scopeSeparator || ','
19 + options.customHeaders = options.customHeaders || {}
20 +
21 + if (!options.customHeaders['User-Agent']) {
22 + options.customHeaders['User-Agent'] = options.userAgent || 'passport-kakao'
23 + }
24 +
25 + return options
26 +}
27 +/**
28 + * KaKaoStrategy 생성자 함수.<br/>
29 + * @param options.clientID 필수. kakao rest app key.
30 + * @param options.callbackURL 필수. 로그인 처리 후 호출할 URL
31 + * @param verify
32 + * @constructor
33 + */
34 +function Strategy(options: StrategyOptions = {}, verify: any) {
35 + OAuth2Strategy.call(this, buildOptions(options), verify)
36 + this.name = 'kakao'
37 + this._userProfileURL = USER_PROFILE_URL
38 +}
39 +
40 +/**
41 + * `OAuth2Stragegy`를 상속 받는다.
42 + */
43 +inherits(Strategy, OAuth2Strategy)
44 +
45 +/**
46 + * kakao 사용자 정보를 얻는다.<br/>
47 + * 사용자 정보를 성공적으로 조회하면 아래의 object가 done 콜백함수 호출과 함꼐 넘어간다.
48 + *
49 + * - `provider` kakao 고정
50 + * - `id` kakao user id number
51 + * - `username` 사용자의 kakao nickname
52 + * - `_raw` json string 원문
53 + * _ `_json` json 원 데이터
54 + *
55 + * @param {String} accessToken
56 + * @param {Function} done
57 + */
58 +Strategy.prototype.userProfile = function(
59 + accessToken: string,
60 + done: (error: Error, profile?: Profile) => void
61 +) {
62 + this._oauth2.get(
63 + this._userProfileURL,
64 + accessToken,
65 + (err: Error, body: string) => {
66 + if (err) {
67 + return done(err)
68 + }
69 +
70 + try {
71 + const json = JSON.parse(body)
72 + // 카카오톡이나 카카오스토리에 연동한 적이 없는 계정의 경우
73 + // properties가 비어있다고 한다. 없을 경우의 처리
74 + const properties = json.properties || {
75 + nickname: '미연동 계정',
76 + }
77 + const profile: Profile = {
78 + provider: 'kakao',
79 + id: json.id,
80 + username: properties.nickname,
81 + displayName: properties.nickname,
82 + _raw: body,
83 + _json: json,
84 + }
85 + return done(null, profile)
86 + } catch (e) {
87 + return done(e)
88 + }
89 + }
90 + )
91 +}
92 +
93 +export default Strategy
1 +import Strategy from './Strategy'
2 +
3 +export default Strategy
4 +
5 +export { Strategy }
1 +export interface StrategyOptions {
2 + authorizationURL?: string
3 + tokenURL?: string
4 + clientSecret?: string
5 + scopeSeparator?: string
6 + customHeaders?: {
7 + 'User-Agent'?: string
8 + }
9 + userAgent?: string
10 +}
11 +
12 +export interface Profile {
13 + provider: 'kakao'
14 + id?: string | number
15 + username?: string
16 + displayName?: string
17 + _raw: string
18 + _json: string
19 +}
1 +import { expect } from 'chai'
2 +import KakaoStrategy, { buildOptions } from '../src/Strategy'
3 +
4 +describe('passport-kakao', () => {
5 + it('passport-kakao 객체가 제대로 생성이 되어 있어야 한다.', () => {
6 + expect(KakaoStrategy).to.not.equals(null)
7 + })
8 + it('Strategy option의 clientSecret 값이 없을 경우 default 값이 설정되어야 한다.', () => {
9 + const options = buildOptions({})
10 +
11 + expect(options).to.not.equals(null)
12 + expect(options.clientSecret).to.be.equals('kakao')
13 + expect(options.scopeSeparator).to.be.equals(',')
14 + expect(options.customHeaders['User-Agent']).to.be.equals('passport-kakao')
15 + })
16 + it('Strategy option의 User-Agent값이 있을 경우 customHeaders의 User-Agent가 해당 값으로 설정되어야 한다.', () => {
17 + const options = buildOptions({
18 + customHeaders: {
19 + 'User-Agent': 'HELLO ROTO',
20 + },
21 + })
22 + expect(options.customHeaders['User-Agent']).to.be.equals('HELLO ROTO')
23 + })
24 +})
1 +{
2 + "include": ["./src"],
3 + "compilerOptions": {
4 + /* Basic Options */
5 + // "incremental": true, /* Enable incremental compilation */
6 + "target": "es5" /* Specify ECMAScript target version: 'ES3' (default), 'ES5', 'ES2015', 'ES2016', 'ES2017', 'ES2018', 'ES2019' or 'ESNEXT'. */,
7 + "module": "commonjs" /* Specify module code generation: 'none', 'commonjs', 'amd', 'system', 'umd', 'es2015', or 'ESNext'. */,
8 + // "lib": [], /* Specify library files to be included in the compilation. */
9 + // "allowJs": true, /* Allow javascript files to be compiled. */
10 + // "checkJs": true, /* Report errors in .js files. */
11 + // "jsx": "preserve", /* Specify JSX code generation: 'preserve', 'react-native', or 'react'. */
12 + // "declaration": true, /* Generates corresponding '.d.ts' file. */
13 + // "declarationMap": true, /* Generates a sourcemap for each corresponding '.d.ts' file. */
14 + // "sourceMap": true, /* Generates corresponding '.map' file. */
15 + // "outFile": "./", /* Concatenate and emit output to single file. */
16 + "outDir": "./dist" /* Redirect output structure to the directory. */,
17 + "rootDir": "./src" /* Specify the root directory of input files. Use to control the output directory structure with --outDir. */,
18 + // "composite": true, /* Enable project compilation */
19 + // "tsBuildInfoFile": "./", /* Specify file to store incremental compilation information */
20 + // "removeComments": true, /* Do not emit comments to output. */
21 + // "noEmit": true, /* Do not emit outputs. */
22 + // "importHelpers": true, /* Import emit helpers from 'tslib'. */
23 + // "downlevelIteration": true, /* Provide full support for iterables in 'for-of', spread, and destructuring when targeting 'ES5' or 'ES3'. */
24 + // "isolatedModules": true, /* Transpile each file as a separate module (similar to 'ts.transpileModule'). */
25 +
26 + /* Strict Type-Checking Options */
27 + "strict": false /* Enable all strict type-checking options. */,
28 + // "noImplicitAny": true, /* Raise error on expressions and declarations with an implied 'any' type. */
29 + // "strictNullChecks": true, /* Enable strict null checks. */
30 + // "strictFunctionTypes": true, /* Enable strict checking of function types. */
31 + // "strictBindCallApply": true, /* Enable strict 'bind', 'call', and 'apply' methods on functions. */
32 + // "strictPropertyInitialization": true, /* Enable strict checking of property initialization in classes. */
33 + // "noImplicitThis": true, /* Raise error on 'this' expressions with an implied 'any' type. */
34 + // "alwaysStrict": true, /* Parse in strict mode and emit "use strict" for each source file. */
35 +
36 + /* Additional Checks */
37 + // "noUnusedLocals": true, /* Report errors on unused locals. */
38 + // "noUnusedParameters": true, /* Report errors on unused parameters. */
39 + // "noImplicitReturns": true, /* Report error when not all code paths in function return a value. */
40 + // "noFallthroughCasesInSwitch": true, /* Report errors for fallthrough cases in switch statement. */
41 +
42 + /* Module Resolution Options */
43 + // "moduleResolution": "node", /* Specify module resolution strategy: 'node' (Node.js) or 'classic' (TypeScript pre-1.6). */
44 + // "baseUrl": "./", /* Base directory to resolve non-absolute module names. */
45 + // "paths": {}, /* A series of entries which re-map imports to lookup locations relative to the 'baseUrl'. */
46 + // "rootDirs": [], /* List of root folders whose combined content represents the structure of the project at runtime. */
47 + // "typeRoots": [], /* List of folders to include type definitions from. */
48 + // "types": [], /* Type declaration files to be included in compilation. */
49 + // "allowSyntheticDefaultImports": true, /* Allow default imports from modules with no default export. This does not affect code emit, just typechecking. */
50 + "esModuleInterop": true /* Enables emit interoperability between CommonJS and ES Modules via creation of namespace objects for all imports. Implies 'allowSyntheticDefaultImports'. */
51 + // "preserveSymlinks": true, /* Do not resolve the real path of symlinks. */
52 + // "allowUmdGlobalAccess": true, /* Allow accessing UMD globals from modules. */
53 +
54 + /* Source Map Options */
55 + // "sourceRoot": "", /* Specify the location where debugger should locate TypeScript files instead of source locations. */
56 + // "mapRoot": "", /* Specify the location where debugger should locate map files instead of generated locations. */
57 + // "inlineSourceMap": true, /* Emit a single file with source maps instead of having a separate file. */
58 + // "inlineSources": true, /* Emit the source alongside the sourcemaps within a single file; requires '--inlineSourceMap' or '--sourceMap' to be set. */
59 +
60 + /* Experimental Options */
61 + // "experimentalDecorators": true, /* Enables experimental support for ES7 decorators. */
62 + // "emitDecoratorMetadata": true, /* Enables experimental support for emitting type metadata for decorators. */
63 + }
64 +}
1 +{
2 + "defaultSeverity": "error",
3 + "extends": ["tslint:latest", "tslint-config-prettier"],
4 + "jsRules": {},
5 + "rules": {
6 + "interface-name": false,
7 + "semicolon": [true, "never"],
8 + "member-access": [false],
9 + "ordered-imports": [false],
10 + "object-literal-sort-keys": [false],
11 + "no-console": [false],
12 + "quotemark": [true, "single", "jsx-double"],
13 + "jsx-no-lambda": [false],
14 + "no-submodule-imports": [false],
15 + "jsx-boolean-value": [false],
16 + "no-implicit-dependencies": [true, "dev"],
17 + "no-empty-interface": [false],
18 + "no-var-requires": [false]
19 + },
20 + "rulesDirectory": []
21 +}
...@@ -1180,6 +1180,32 @@ ...@@ -1180,6 +1180,32 @@
1180 "passport-oauth2": "1.x.x" 1180 "passport-oauth2": "1.x.x"
1181 } 1181 }
1182 }, 1182 },
1183 + "passport-kakao": {
1184 + "version": "1.0.0",
1185 + "resolved": "https://registry.npmjs.org/passport-kakao/-/passport-kakao-1.0.0.tgz",
1186 + "integrity": "sha512-rOR3+8g1bev/p9ChZLDKQan9oBmSSA2hmb7yQKdBOsjyF1mijx7fgR05pTWPz3g5r0kHZ2Y44sT2Ys6wJQq0xQ==",
1187 + "requires": {
1188 + "passport-oauth2": "~1.1.2",
1189 + "pkginfo": "~0.3.0"
1190 + },
1191 + "dependencies": {
1192 + "passport-oauth2": {
1193 + "version": "1.1.2",
1194 + "resolved": "https://registry.npmjs.org/passport-oauth2/-/passport-oauth2-1.1.2.tgz",
1195 + "integrity": "sha1-vXFjsbYJA3GGjcTvb58uHkzEuUg=",
1196 + "requires": {
1197 + "oauth": "0.9.x",
1198 + "passport-strategy": "1.x.x",
1199 + "uid2": "0.0.x"
1200 + }
1201 + },
1202 + "pkginfo": {
1203 + "version": "0.3.1",
1204 + "resolved": "https://registry.npmjs.org/pkginfo/-/pkginfo-0.3.1.tgz",
1205 + "integrity": "sha1-Wyn2qB9wcXFC4J52W76rl7T4HiE="
1206 + }
1207 + }
1208 + },
1183 "passport-oauth": { 1209 "passport-oauth": {
1184 "version": "0.1.15", 1210 "version": "0.1.15",
1185 "resolved": "https://registry.npmjs.org/passport-oauth/-/passport-oauth-0.1.15.tgz", 1211 "resolved": "https://registry.npmjs.org/passport-oauth/-/passport-oauth-0.1.15.tgz",
......
...@@ -25,6 +25,7 @@ ...@@ -25,6 +25,7 @@
25 "needle": "^2.4.0", 25 "needle": "^2.4.0",
26 "passport": "^0.4.0", 26 "passport": "^0.4.0",
27 "passport-google-oauth": "^2.0.0", 27 "passport-google-oauth": "^2.0.0",
28 - "passport-google-oauth20": "^1.0.0" 28 + "passport-google-oauth20": "^1.0.0",
29 + "passport-kakao": "^1.0.0"
29 } 30 }
30 } 31 }
......
1 var express = require('express'); 1 var express = require('express');
2 var router = express.Router(); 2 var router = express.Router();
3 var gcal = require('google-calendar'); 3 var gcal = require('google-calendar');
4 -var accessToken;
5 4
6 -var id;
7 var accessToken; 5 var accessToken;
6 +var id;
7 +
8 8
9 router.get('/', function(req, res, next) { 9 router.get('/', function(req, res, next) {
10 console.log(accessToken); 10 console.log(accessToken);
...@@ -88,7 +88,6 @@ var timestamp = function (date) { ...@@ -88,7 +88,6 @@ var timestamp = function (date) {
88 + ":" + pad(Math.abs(offset) % 60, 2); 88 + ":" + pad(Math.abs(offset) % 60, 2);
89 } 89 }
90 90
91 -
92 module.exports = router; 91 module.exports = router;
93 92
94 //timestamp(new Date(1983, 4, 9, 11, 5, 17)); 93 //timestamp(new Date(1983, 4, 9, 11, 5, 17));
...\ No newline at end of file ...\ No newline at end of file
......
...@@ -4,14 +4,15 @@ const fs = require('fs'); ...@@ -4,14 +4,15 @@ const fs = require('fs');
4 const readline = require('readline'); 4 const readline = require('readline');
5 const {google} = require('googleapis'); 5 const {google} = require('googleapis');
6 const bodyParser = require('body-parser'); 6 const bodyParser = require('body-parser');
7 +const KakaoStrategy = require("passport-kakao").Strategy;
7 8
8 var passport = require('passport'); 9 var passport = require('passport');
9 var GoogleStrategy = require('passport-google-oauth').OAuth2Strategy; 10 var GoogleStrategy = require('passport-google-oauth').OAuth2Strategy;
10 var gcal = require('google-calendar'); 11 var gcal = require('google-calendar');
11 12
12 passport.use(new GoogleStrategy({ 13 passport.use(new GoogleStrategy({
13 - clientID:'978869138601-u3euf0c04sbdor68r30m599gilvjn91e.apps.googleusercontent.com', 14 + clientID:CLIENTID,
14 - clientSecret:'N7Uh_oVQZt-almzA4DkM4bm_', 15 + clientSecret:CLIENTSECRET,
15 callbackURL:'http://localhost:3000/auth/google/callback', 16 callbackURL:'http://localhost:3000/auth/google/callback',
16 scope:['openid','email','https://www.googleapis.com/auth/calendar.readonly', 17 scope:['openid','email','https://www.googleapis.com/auth/calendar.readonly',
17 'https://www.googleapis.com/auth/calendar', 18 'https://www.googleapis.com/auth/calendar',
...@@ -30,6 +31,27 @@ router.get('/auth/google/callback',passport.authenticate('google',{ ...@@ -30,6 +31,27 @@ router.get('/auth/google/callback',passport.authenticate('google',{
30 res.redirect('/calendar'); 31 res.redirect('/calendar');
31 }); 32 });
32 33
34 +const kakaoKey = {
35 + clientID: KAKAO_API_KEY,
36 + callbackURL: "/oauth/callback"
37 +};
38 +
39 +passport.use(
40 + "kakao-login",
41 + new KakaoStrategy(kakaoKey, (accessToken, refreshToken, profile, done) => {
42 + console.log(profile);
43 + return done(null,profile);
44 + })
45 +);
46 +router.get("/kakao", passport.authenticate("kakao-login"));
47 +router.get(
48 + "/oauth/callback",
49 + passport.authenticate("kakao-login",{failureRedirect:'/'}),function(req, res) {
50 + req.session.access_token = req.user.accessToken;
51 + res.redirect('/');
52 + });
53 +
54 +
33 calList = new Array(); 55 calList = new Array();
34 Calendars = new Array(); 56 Calendars = new Array();
35 57
......
1 +var express = require('express');
2 +var router = express.Router();
3 +
4 +/* GET users listing. */
5 +router.get('/', function(req, res, next) {
6 + console.log("accepted");
7 +});
8 +
9 +module.exports = router;
...@@ -11,5 +11,7 @@ ...@@ -11,5 +11,7 @@
11 <form action='/auth/google' method='GET'> 11 <form action='/auth/google' method='GET'>
12 <input type="submit" name='submit' value='로그인'/> 12 <input type="submit" name='submit' value='로그인'/>
13 </form> 13 </form>
14 + <form action='/kakao' method='GET'>
15 + <input type="submit" name='submit' value='로그인'/>
14 </body> 16 </body>
15 </html> 17 </html>
...\ No newline at end of file ...\ No newline at end of file
......