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) { | ... | ... |
node_modules/passport-kakao/.prettierrc
0 → 100644
node_modules/passport-kakao/.travis.yml
0 → 100644
node_modules/passport-kakao/README.md
0 → 100644
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 모듈을 참고함. |
node_modules/passport-kakao/dist/Strategy.js
0 → 100644
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 | +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 | +(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/)> |
node_modules/passport-kakao/node_modules/passport-oauth2/lib/errors/authorizationerror.js
0 → 100644
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; |
node_modules/passport-kakao/node_modules/passport-oauth2/lib/errors/internaloautherror.js
0 → 100644
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; |
This diff is collapsed. Click to expand it.
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 | +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 |
This diff is collapsed. Click to expand it.
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); |
node_modules/passport-kakao/package.json
0 → 100644
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.
node_modules/passport-kakao/sample/sample.js
0 → 100644
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 | +} |
node_modules/passport-kakao/src/Strategy.ts
0 → 100644
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 | +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 | +}) |
node_modules/passport-kakao/tsconfig.json
0 → 100644
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 | +} |
node_modules/passport-kakao/tslint.json
0 → 100644
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 | ... | ... |
routes/login.js
0 → 100644
... | @@ -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 | ... | ... |
-
Please register or login to post a comment