sb-omniauth-kakao 0.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/.github/workflows/gem-push.yml +59 -0
- data/.gitignore +20 -0
- data/.rspec +2 -0
- data/Gemfile +4 -0
- data/Guardfile +8 -0
- data/README.md +109 -0
- data/Rakefile +2 -0
- data/example/.env.sample +11 -0
- data/example/Gemfile +24 -0
- data/example/Makefile +12 -0
- data/example/config.ru +298 -0
- data/lib/omniauth/strategies/kakao.rb +107 -0
- data/lib/sb-omniauth-kakao/version.rb +5 -0
- data/lib/sb-omniauth-kakao.rb +2 -0
- data/sb-omniauth-kakao.gemspec +33 -0
- data/spec/omniauth/strategies/kakao_spec.rb +193 -0
- data/spec/spec_helper.rb +23 -0
- metadata +172 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: 77c1345c76240dd09af334a012ffb81c043287b98643240f35de32343db8f1b8
|
4
|
+
data.tar.gz: c752d5bc9a586418d427dc0335cb01e01f41a74503b8c70a7962f44ac09863c2
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 35f4fd5bb3ec8ac00b694c36694d89c489a5c82e0f7a16d8282060de5e002c3caf1000362104b5bce09820d2d987ebefe1fb48d77759c06f65dcc455520ee0c8
|
7
|
+
data.tar.gz: f1981fdb8050d211d835c0a80ddacb34c32be3c2e0fe5a0988b81578e11ac2be5460468913e02dcfe31bec2b356dea59326da8073ecf62a9d74fd135960b45dc
|
@@ -0,0 +1,59 @@
|
|
1
|
+
name: Ruby Gem
|
2
|
+
|
3
|
+
on:
|
4
|
+
push:
|
5
|
+
branches: [ "master" ]
|
6
|
+
pull_request:
|
7
|
+
branches: [ "master" ]
|
8
|
+
|
9
|
+
jobs:
|
10
|
+
build-publish-gh-packages:
|
11
|
+
name: Build + Publish - GithubPackages
|
12
|
+
runs-on: ubuntu-latest
|
13
|
+
permissions:
|
14
|
+
contents: read
|
15
|
+
packages: write
|
16
|
+
|
17
|
+
steps:
|
18
|
+
- uses: actions/checkout@v4
|
19
|
+
- name: Set up Ruby matrix
|
20
|
+
uses: ruby/setup-ruby@v1
|
21
|
+
with:
|
22
|
+
ruby-version: '3.3'
|
23
|
+
|
24
|
+
- name: Publish to Github Packages
|
25
|
+
run: |
|
26
|
+
mkdir -p $HOME/.gem
|
27
|
+
touch $HOME/.gem/credentials
|
28
|
+
chmod 0600 $HOME/.gem/credentials
|
29
|
+
printf -- "---\n:github: ${GEM_HOST_API_KEY}\n" > $HOME/.gem/credentials
|
30
|
+
gem build *.gemspec
|
31
|
+
gem push --KEY github --host https://rubygems.pkg.github.com/${OWNER} *.gem
|
32
|
+
env:
|
33
|
+
GEM_HOST_API_KEY: "Bearer ${{secrets.GITHUB_TOKEN}}"
|
34
|
+
OWNER: ${{ github.repository_owner }}
|
35
|
+
|
36
|
+
|
37
|
+
build-publish-rubygems:
|
38
|
+
name: Build + Publish - Rubygems
|
39
|
+
runs-on: ubuntu-latest
|
40
|
+
permissions:
|
41
|
+
contents: read
|
42
|
+
|
43
|
+
steps:
|
44
|
+
- uses: actions/checkout@v4
|
45
|
+
- name: Set up Ruby matrix
|
46
|
+
uses: ruby/setup-ruby@v1
|
47
|
+
with:
|
48
|
+
ruby-version: '3.3'
|
49
|
+
|
50
|
+
- name: Publish to RubyGems
|
51
|
+
run: |
|
52
|
+
mkdir -p $HOME/.gem
|
53
|
+
touch $HOME/.gem/credentials
|
54
|
+
chmod 0600 $HOME/.gem/credentials
|
55
|
+
printf -- "---\n:rubygems_api_key: ${GEM_HOST_API_KEY}\n" > $HOME/.gem/credentials
|
56
|
+
gem build *.gemspec
|
57
|
+
gem push *.gem
|
58
|
+
env:
|
59
|
+
GEM_HOST_API_KEY: "${{secrets.RUBYGEMS_AUTH_TOKEN}}"
|
data/.gitignore
ADDED
data/.rspec
ADDED
data/Gemfile
ADDED
data/Guardfile
ADDED
@@ -0,0 +1,8 @@
|
|
1
|
+
# A sample Guardfile
|
2
|
+
# More info at https://github.com/guard/guard#readme
|
3
|
+
|
4
|
+
guard :rspec, :cmd => "bundle exec rspec spec" do
|
5
|
+
watch(%r{^spec/.+_spec\.rb$})
|
6
|
+
watch(%r{^lib/(.+)\.rb$}) { |m| "spec/lib/#{m[1]}_spec.rb" }
|
7
|
+
watch('spec/spec_helper.rb') { "spec" }
|
8
|
+
end
|
data/README.md
ADDED
@@ -0,0 +1,109 @@
|
|
1
|
+
# SB OmniAuth Kakao
|
2
|
+
|
3
|
+
omniauth-kakao을 쓰려고 보니 에러나는데 업데이트가 안되는 것 같아서 수정
|
4
|
+
하다보니 ommniauth도 이상한 것 같아서 보다보니 끝이 없다.
|
5
|
+
oauth2는 다 좋은데 왜 로깅이 안되는걸까
|
6
|
+
|
7
|
+
[카카오](http://www.kakao.com/) 인증을 위한 OmniAuth strategy 입니다. [카카오 개발자 페이지](http://developers.kakao.com)에서 REST API 키를 생성한 뒤 이용해 주세요. 자세한 사항은 [시작하기 - 앱 생성](https://developers.kakao.com/docs/restapi#시작하기-앱-생성) 페이지를 참고하시기 바랍니다.
|
8
|
+
|
9
|
+
## Installation
|
10
|
+
|
11
|
+
Add to your `Gemfile`:
|
12
|
+
```ruby
|
13
|
+
gem 'sb-omniauth-kakao', git: git@github.com:ScriptonBasestar/sb-omniauth-kakao.git
|
14
|
+
|
15
|
+
or
|
16
|
+
|
17
|
+
gem "sb-omniauth-kakao", "0.3.0", source: "https://rubygems.pkg.github.com/scriptonbasestar"
|
18
|
+
|
19
|
+
or
|
20
|
+
|
21
|
+
# https://github.com/ScriptonBasestar/sb-omniauth-kakao/pkgs/rubygems/sb-omniauth-kakao
|
22
|
+
source "https://rubygems.pkg.github.com/scriptonbasestar" do
|
23
|
+
gem "sb-omniauth-kakao", "0.3.0"
|
24
|
+
end
|
25
|
+
```
|
26
|
+
|
27
|
+
Then `bundle install`.
|
28
|
+
|
29
|
+
## Usage
|
30
|
+
|
31
|
+
### Rails
|
32
|
+
|
33
|
+
Rails Middleware 편집
|
34
|
+
|
35
|
+
`config/initializers/omniauth.rb`:
|
36
|
+
```ruby
|
37
|
+
Rails.application.config.middleware.use OmniAuth::Builder do
|
38
|
+
# 3 중 1
|
39
|
+
provider :kakao, ENV['KAKAO_CLIENT_ID']
|
40
|
+
provider :kakao, ENV['KAKAO_CLIENT_ID'], ENV['KAKAO_CLIENT_SECRET']
|
41
|
+
provider :kakao, ENV['KAKAO_CLIENT_ID'], {:redirect_path => ENV['REDIRECT_PATH']}
|
42
|
+
end
|
43
|
+
```
|
44
|
+
|
45
|
+
Then go to [My Application](https://developers.kakao.com/apps) page, select your current application and add your domain address(ex: http://localhost:3000/) to 'Setting - Platform - Web - Site Domain'.
|
46
|
+
|
47
|
+
그리고 [내 어플리케이션](https://developers.kakao.com/apps)에서 현재 어플리케이션을 선택하고, '설정 - 플랫폼 - 웹 - 사이트 도메인'에 도메인 주소(예: http://localhost:3000/)를 넣어주세요.
|
48
|
+
|
49
|
+

|
50
|
+
|
51
|
+
For more information, please read the [OmniAuth](https://github.com/intridea/omniauth) docs for detailed instructions.
|
52
|
+
|
53
|
+
더 자세한 사항은 [OmniAuth](https://github.com/intridea/omniauth)의 문서를 참고해 주세요.
|
54
|
+
|
55
|
+
## Example
|
56
|
+
|
57
|
+
You can test omniauth-kakao in the `example/` folder.
|
58
|
+
|
59
|
+
`example/` 폴더에 있는 예제를 통해 omniauth-kakao를 테스트해볼 수 있습니다.
|
60
|
+
|
61
|
+
```
|
62
|
+
cd example/
|
63
|
+
bundle install
|
64
|
+
KAKAO_CLIENT_ID='<your-kakako-client-id>' ruby app.rb
|
65
|
+
|
66
|
+
# 또는 Redirect Path를 설정하고 싶다면(or if you want to customize your Redirect Path)
|
67
|
+
# KAKAO_CLIENT_ID='<your-kakako-client-id>' REDIRECT_PATH='<your-redirect-path>' ruby app.rb
|
68
|
+
```
|
69
|
+
|
70
|
+
Then open `http://localhost:4567/` in your browser.
|
71
|
+
|
72
|
+
이후 `http://localhost:4567/`로 접속하시면 됩니다.
|
73
|
+
|
74
|
+
Warning: Do not forgot to add `http://localhost:4567/` in [My Application](https://developers.kakao.com/apps).
|
75
|
+
|
76
|
+
주의: [내 어플리케이션](https://developers.kakao.com/apps) 의 '설정된 플랫폼 - 웹 - 사이트 도메인'에 `http://localhost:4567/`을 넣는 걸 잊지 마세요.
|
77
|
+
|
78
|
+
## Auth Hash
|
79
|
+
|
80
|
+
Here's an example *Auth Hash* available in `request.env['omniauth.auth']`:
|
81
|
+
|
82
|
+
`request.env['omniauth.auth']` 안에 들어있는 *Auth Hash* 는 다음과 같습니다.
|
83
|
+
|
84
|
+
```ruby
|
85
|
+
{
|
86
|
+
:provider => 'kakao',
|
87
|
+
:uid => '123456789',
|
88
|
+
:info => {
|
89
|
+
:name => 'Hong Gil-Dong',
|
90
|
+
:image => 'http://xxx.kakao.com/.../aaa.jpg',
|
91
|
+
},
|
92
|
+
:credentials => {
|
93
|
+
:token => 'ABCDEF...', # OAuth 2.0 access_token, which you may wish to store.
|
94
|
+
:refresh_token => 'OPQRST...', # OAuth 2.0 refresh_token.
|
95
|
+
:expires_at => 1321747205, # when the access token expires (it always will)
|
96
|
+
:expires => true # this will always be true
|
97
|
+
},
|
98
|
+
:extra => {
|
99
|
+
:properties => {
|
100
|
+
:nickname => 'Hong Gil-Dong',
|
101
|
+
:thumbnail_image => 'http://xxx.kakao.com/.../aaa.jpg'
|
102
|
+
:profile_image => 'http://xxx.kakao.com/.../bbb.jpg'
|
103
|
+
}
|
104
|
+
}
|
105
|
+
}
|
106
|
+
```
|
107
|
+
|
108
|
+
## Contributors
|
109
|
+
Issue or Fork PR
|
data/Rakefile
ADDED
data/example/.env.sample
ADDED
@@ -0,0 +1,11 @@
|
|
1
|
+
KAKAO_CLIENT_ID=your_kakao_client_id
|
2
|
+
KAKAO_CLIENT_SECRET=your_kakao_client_secret
|
3
|
+
KAKAO_CLIENT_SCOPE=profile,account_email
|
4
|
+
KAKAO_REDIRECT_URL=http://localhost:3000/auth/kakao/callback
|
5
|
+
|
6
|
+
GOOGLE_CLIENT_ID=your_google_client_id
|
7
|
+
GOOGLE_CLIENT_SECRET=your_google_client_secret
|
8
|
+
|
9
|
+
RACK_COOKIE_SECRET=a3f5e6d7c8b9a0b1c2d3e4f5a6b7c8d9e0f1a2b3c4d5e6f7a8b9c0d1e2f3a4b5
|
10
|
+
|
11
|
+
OAUTH_DEBUG=true
|
data/example/Gemfile
ADDED
@@ -0,0 +1,24 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
source "https://rubygems.org"
|
4
|
+
|
5
|
+
group :development, :test do
|
6
|
+
gem "growl"
|
7
|
+
gem "guard"
|
8
|
+
gem "guard-bundler"
|
9
|
+
gem "guard-rspec"
|
10
|
+
gem "rb-fsevent"
|
11
|
+
|
12
|
+
gem "dotenv"
|
13
|
+
|
14
|
+
gem "sb-omniauth-kakao", path: "../"
|
15
|
+
|
16
|
+
gem "byebug"
|
17
|
+
|
18
|
+
gem "sinatra"
|
19
|
+
|
20
|
+
gem "puma"
|
21
|
+
gem "rackup"
|
22
|
+
|
23
|
+
gem "rerun"
|
24
|
+
end
|
data/example/Makefile
ADDED
data/example/config.ru
ADDED
@@ -0,0 +1,298 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "rubygems"
|
4
|
+
require "bundler"
|
5
|
+
require "sinatra"
|
6
|
+
require "omniauth"
|
7
|
+
require "faraday"
|
8
|
+
require "logger"
|
9
|
+
require "byebug"
|
10
|
+
|
11
|
+
require "sb-omniauth-kakao"
|
12
|
+
|
13
|
+
require "dotenv"
|
14
|
+
Dotenv.load
|
15
|
+
|
16
|
+
# Do not use for production code.
|
17
|
+
# This is only to make setup easier when running through the sample.
|
18
|
+
#
|
19
|
+
# If you do have issues with certs in production code, this could help:
|
20
|
+
# http://railsapps.github.io/openssl-certificate-verify-failed.html
|
21
|
+
# OpenSSL::SSL::VERIFY_PEER = OpenSSL::SSL::VERIFY_NONE
|
22
|
+
|
23
|
+
class App < Sinatra::Base
|
24
|
+
configure do
|
25
|
+
set :sessions, true
|
26
|
+
set :inline_templates, true
|
27
|
+
|
28
|
+
# STDOUT의 sync 활성화로 버퍼링 방지
|
29
|
+
STDOUT.sync = true
|
30
|
+
|
31
|
+
# 로깅 설정
|
32
|
+
$logger = Logger.new(STDOUT)
|
33
|
+
$logger.level = Logger::DEBUG
|
34
|
+
|
35
|
+
# Sinatra 로깅 활성화
|
36
|
+
enable :logging
|
37
|
+
set :logger, $logger
|
38
|
+
end
|
39
|
+
|
40
|
+
before do
|
41
|
+
env["rack.logger"] = $logger
|
42
|
+
end
|
43
|
+
|
44
|
+
use Rack::Session::Cookie, secret: ENV.fetch("RACK_COOKIE_SECRET", "a3f5e6d7c8b9a0b1c2d3e4f5a6b7c8d9e0f1a2b3c4d5e6f7a8b9c0d1e2f3a4b5")
|
45
|
+
|
46
|
+
# OAuth2 클라이언트의 로거를 Sinatra의 로거로 설정
|
47
|
+
OAuth2::Client.class_eval do
|
48
|
+
define_method(:logger) { $logger }
|
49
|
+
end
|
50
|
+
OmniAuth.config.logger = $logger
|
51
|
+
use OmniAuth::Builder do
|
52
|
+
# provider :kakao, ENV.fetch("KAKAO_CLIENT_ID", nil), ENV.fetch("KAKAO_CLIENT_SECRET", nil), access_type: "offline", prompt: "consent", provider_ignores_state: true, scope: "account_email,profile", :strategy_class => OmniAuth::Strategies::KakaoOauth2
|
53
|
+
# provider :kakao, ENV.fetch("KAKAO_CLIENT_ID", nil), ENV.fetch("KAKAO_CLIENT_SECRET", nil),
|
54
|
+
# scope: ENV.fetch("KAKAO_CLIENT_SCOPE", "profile"),
|
55
|
+
# client_options: {
|
56
|
+
# connection_build: lambda do |builder|
|
57
|
+
# builder.request :url_encoded
|
58
|
+
# builder.response :logger, $logger
|
59
|
+
# builder.adapter Faraday.default_adapter
|
60
|
+
# end
|
61
|
+
# }
|
62
|
+
provider :kakao, ENV.fetch("KAKAO_CLIENT_ID", nil), ENV.fetch("KAKAO_CLIENT_SECRET", nil),
|
63
|
+
scope: ENV.fetch("KAKAO_CLIENT_SCOPE", "profile"), redirect_url: ENV.fetch("KAKAO_REDIRECT_URL") do |builder|
|
64
|
+
builder.client_options.connection_build do |conn|
|
65
|
+
conn.request :url_encoded
|
66
|
+
conn.response :logger, $logger, { headers: true, bodies: { request: false, response: true }, errors: true }
|
67
|
+
conn.adapter Faraday.default_adapter
|
68
|
+
end
|
69
|
+
# connection_build
|
70
|
+
|
71
|
+
# provider :kakao, "bcf75d0d9b0781ac4305d8750972ce25", "W7oQ3tX4Z9wj9gPJRqFlJ2waVVLTLfY8",
|
72
|
+
# scope: "profile,account_email" do |builder|
|
73
|
+
# builder.request :url_encoded
|
74
|
+
# # builder.response :logger, $logger, bodies: true
|
75
|
+
# builder.response :logger, $logger, { headers: true, bodies: { request: false, response: true }, errors: true }
|
76
|
+
# builder.adapter Faraday.default_adapter
|
77
|
+
end
|
78
|
+
# before_request_phase do |env|
|
79
|
+
# puts "before_request_phase >>>>>>>>>>"
|
80
|
+
# puts env["rack.session"]
|
81
|
+
# puts env["rack.session"]["user_params"]
|
82
|
+
# puts env["rack.request.form_hash"]["user"]
|
83
|
+
# request_env = env['omniauth.auth']
|
84
|
+
# print request_env
|
85
|
+
# puts "before_request_phase <<<<<<<<<<"
|
86
|
+
# end
|
87
|
+
# before_callback_phase do |env|
|
88
|
+
# puts "before_callback_phase >>>>>>>>>>"
|
89
|
+
# request_env = env['omniauth.auth']
|
90
|
+
# puts "=== OmniAuth Request ==="
|
91
|
+
# puts request_env.to_hash if request_env
|
92
|
+
#
|
93
|
+
# # puts env["rack.session"]
|
94
|
+
# # puts env["rack.session"]["user_params"]
|
95
|
+
# # puts env["rack.request.form_hash"]["user"]
|
96
|
+
# puts "before_callback_phase <<<<<<<<<<"
|
97
|
+
# end
|
98
|
+
puts "OmniAuth::Strategies::KakaoOauth2"
|
99
|
+
puts "KAKAO_CLIENT_ID: #{ENV.fetch("KAKAO_CLIENT_ID", nil)}"
|
100
|
+
puts "KAKAO_CLIENT_SECRET: #{ENV.fetch("KAKAO_CLIENT_SECRET", nil)}"
|
101
|
+
# on_failure do |env|
|
102
|
+
# error = env["omniauth.error"]
|
103
|
+
# puts "OmniAuth error: #{error.inspect}"
|
104
|
+
# OmniAuth::FailureEndpoint.new(env).redirect_to_failure
|
105
|
+
# end
|
106
|
+
end
|
107
|
+
|
108
|
+
get "/" do
|
109
|
+
logger.info "========================================================"
|
110
|
+
logger.debug "========================================================"
|
111
|
+
logger.info "route GET /"
|
112
|
+
<<-HTML
|
113
|
+
<!DOCTYPE html>
|
114
|
+
<html>
|
115
|
+
<head>
|
116
|
+
<title>Kakao OAuth2 Example</title>
|
117
|
+
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script>
|
118
|
+
<script>
|
119
|
+
jQuery(function() {
|
120
|
+
return $.ajax({
|
121
|
+
url: 'https://apis.google.com/js/client:plus.js?onload=gpAsyncInit',
|
122
|
+
dataType: 'script',
|
123
|
+
cache: true
|
124
|
+
});
|
125
|
+
});
|
126
|
+
|
127
|
+
window.gpAsyncInit = function() {
|
128
|
+
gapi.auth.authorize({
|
129
|
+
immediate: true,
|
130
|
+
response_type: 'code',
|
131
|
+
cookie_policy: 'single_host_origin',
|
132
|
+
client_id: "#{ENV.fetch("KAKAO_CLIENT_ID", nil)}",
|
133
|
+
scope: 'account_email profile'
|
134
|
+
}, function(response) {
|
135
|
+
return;
|
136
|
+
});
|
137
|
+
$('.kakao-login').click(function(e) {
|
138
|
+
e.preventDefault();
|
139
|
+
gapi.auth.authorize({
|
140
|
+
immediate: false,
|
141
|
+
response_type: 'code',
|
142
|
+
cookie_policy: 'single_host_origin',
|
143
|
+
client_id: "#{ENV.fetch("KAKAO_CLIENT_ID", nil)}",
|
144
|
+
# scope: 'account_email profile'
|
145
|
+
scope: 'profile'
|
146
|
+
}, function(response) {
|
147
|
+
if (response && !response.error) {
|
148
|
+
// kakao authentication succeed, now post data to server.
|
149
|
+
jQuery.ajax({type: 'POST', url: "/auth/kakao/callback", data: response,
|
150
|
+
success: function(data) {
|
151
|
+
// Log the data returning from kakao.
|
152
|
+
console.log(data)
|
153
|
+
}
|
154
|
+
});
|
155
|
+
} else {
|
156
|
+
// kakao authentication failed.
|
157
|
+
console.log("FAILED")
|
158
|
+
}
|
159
|
+
});
|
160
|
+
});
|
161
|
+
};
|
162
|
+
</script>
|
163
|
+
</head>
|
164
|
+
<body>
|
165
|
+
<ul>
|
166
|
+
<li>
|
167
|
+
<form method='post' action='/auth/kakao'>
|
168
|
+
<input type="hidden" name="authenticity_token" value="#{request.env["rack.session"]["csrf"]}">
|
169
|
+
<button type='submit'>Login with Kakao</button>
|
170
|
+
</form>
|
171
|
+
</li>
|
172
|
+
<li><a href='#' class="kakao-login">Sign in with Kakao via AJAX</a></li>
|
173
|
+
</ul>
|
174
|
+
</body>
|
175
|
+
</html>
|
176
|
+
HTML
|
177
|
+
end
|
178
|
+
|
179
|
+
helpers do
|
180
|
+
def render_callback_page(auth, url)
|
181
|
+
<<-HTML
|
182
|
+
<!DOCTYPE html>
|
183
|
+
<html lang="en">
|
184
|
+
<head>
|
185
|
+
<meta charset="UTF-8">
|
186
|
+
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
187
|
+
<title>OmniAuth Callback - #{url}</title>
|
188
|
+
<style>
|
189
|
+
body {
|
190
|
+
font-family: Arial, sans-serif;
|
191
|
+
margin: 0;
|
192
|
+
padding: 0;
|
193
|
+
background-color: #f9f9f9;
|
194
|
+
color: #333;
|
195
|
+
}
|
196
|
+
header {
|
197
|
+
background-color: #4CAF50;
|
198
|
+
color: white;
|
199
|
+
padding: 1rem;
|
200
|
+
text-align: center;
|
201
|
+
}
|
202
|
+
.container {
|
203
|
+
max-width: 800px;
|
204
|
+
margin: 2rem auto;
|
205
|
+
padding: 1rem;
|
206
|
+
background: white;
|
207
|
+
border-radius: 8px;
|
208
|
+
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
|
209
|
+
}
|
210
|
+
h1 {
|
211
|
+
font-size: 1.5rem;
|
212
|
+
margin-bottom: 1rem;
|
213
|
+
}
|
214
|
+
pre {
|
215
|
+
background: #f4f4f4;
|
216
|
+
padding: 1rem;
|
217
|
+
border-radius: 8px;
|
218
|
+
overflow-x: auto;
|
219
|
+
font-size: 0.9rem;
|
220
|
+
}
|
221
|
+
</style>
|
222
|
+
</head>
|
223
|
+
<body>
|
224
|
+
<header>
|
225
|
+
<h1>OmniAuth Callback - #{url}</h1>
|
226
|
+
</header>
|
227
|
+
<div class="container">
|
228
|
+
<h1>#{params[:provider].capitalize} Callback Success</h1>
|
229
|
+
<p>The callback from <strong>#{params[:provider].capitalize}</strong> was successful. Below is the data received:</p>
|
230
|
+
<pre>#{JSON.pretty_generate(auth)}</pre>
|
231
|
+
</div>
|
232
|
+
</body>
|
233
|
+
</html>
|
234
|
+
HTML
|
235
|
+
end
|
236
|
+
end
|
237
|
+
|
238
|
+
post "/auth/:provider/callback" do
|
239
|
+
logger.info "========================================================"
|
240
|
+
logger.info "route POST /auth/:provider/callback"
|
241
|
+
# content_type "text/plain"
|
242
|
+
begin
|
243
|
+
logger.info "begin"
|
244
|
+
auth = request.env["omniauth.auth"]
|
245
|
+
logger.info auth
|
246
|
+
logger.info auth.to_hash
|
247
|
+
# request.env["omniauth.auth"].to_hash.inspect
|
248
|
+
|
249
|
+
render_callback_page(auth, request.url)
|
250
|
+
rescue StandardError
|
251
|
+
"No Data"
|
252
|
+
end
|
253
|
+
end
|
254
|
+
|
255
|
+
get "/auth/:provider/callback" do
|
256
|
+
logger.info "========================================================"
|
257
|
+
logger.info "route GET /auth/:provider/callback"
|
258
|
+
# content_type "text/plain"
|
259
|
+
begin
|
260
|
+
logger.info "begin"
|
261
|
+
auth = request.env["omniauth.auth"]
|
262
|
+
logger.info auth
|
263
|
+
logger.info auth.to_hash
|
264
|
+
# request.env["omniauth.auth"].to_hash.inspect
|
265
|
+
|
266
|
+
render_callback_page(auth, request.url)
|
267
|
+
rescue StandardError
|
268
|
+
"No Data"
|
269
|
+
end
|
270
|
+
end
|
271
|
+
|
272
|
+
get "/auth/failure" do
|
273
|
+
logger.info "========================================================"
|
274
|
+
logger.info "route GET /auth/failure"
|
275
|
+
begin
|
276
|
+
logger.info "begin"
|
277
|
+
logger.info request.env["omniauth.auth"]
|
278
|
+
logger.info request.env["omniauth.auth"].to_hash
|
279
|
+
request.env["omniauth.auth"].to_hash.inspect
|
280
|
+
rescue StandardError
|
281
|
+
<<-HTML
|
282
|
+
<!DOCTYPE html>
|
283
|
+
<html>
|
284
|
+
<head>
|
285
|
+
<title>Kakao OAuth2 Example</title>
|
286
|
+
</head>
|
287
|
+
<body>
|
288
|
+
<h1>No Data</h1>
|
289
|
+
<p>Request Params: #{request.params.inspect}</p>
|
290
|
+
</body>
|
291
|
+
</html>
|
292
|
+
HTML
|
293
|
+
end
|
294
|
+
end
|
295
|
+
end
|
296
|
+
|
297
|
+
use Rack::CommonLogger, $logger
|
298
|
+
run App.new
|
@@ -0,0 +1,107 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "omniauth-oauth2"
|
4
|
+
|
5
|
+
module OmniAuth
|
6
|
+
module Strategies
|
7
|
+
class Kakao < OmniAuth::Strategies::OAuth2
|
8
|
+
DEFAULT_SCOPE = "account_email,profile".freeze
|
9
|
+
|
10
|
+
BASE_URL = "https://kauth.kakao.com".freeze
|
11
|
+
AUTHORIZE_URL = "/oauth/authorize".freeze
|
12
|
+
AUTHORIZE_TOKEN_URL = "/oauth/token".freeze
|
13
|
+
|
14
|
+
TOKEN_INFO_URL = "/oauth/tokeninfo".freeze
|
15
|
+
|
16
|
+
OPENID_CONFIG_URL = "https://kauth.kakao.com/.well-known/openid-configuration".freeze
|
17
|
+
|
18
|
+
# USER_INFO_URL = 'v1/oidc/userinfo'
|
19
|
+
USER_INFO_URL = "https://kapi.kakao.com/v2/user/me".freeze
|
20
|
+
|
21
|
+
option :name, :kakao
|
22
|
+
|
23
|
+
option :client_options,
|
24
|
+
site: BASE_URL,
|
25
|
+
authorize_url: AUTHORIZE_URL,
|
26
|
+
token_url: AUTHORIZE_TOKEN_URL
|
27
|
+
|
28
|
+
uid {
|
29
|
+
OmniAuth.logger.send :debug, "uid >>>>>>>>>>"
|
30
|
+
raw_info["id"].to_s
|
31
|
+
}
|
32
|
+
|
33
|
+
info do
|
34
|
+
OmniAuth.logger.send :debug, "info >>>>>>>>>>"
|
35
|
+
hash = {
|
36
|
+
name: raw_info["properties"]["nickname"],
|
37
|
+
username: raw_info["kakao_account"]["email"],
|
38
|
+
image: raw_info["properties"]["thumbnail_image"]
|
39
|
+
}
|
40
|
+
if raw_info["kakao_account"]["has_email"] && raw_info["kakao_account"]["is_email_verified"] && raw_info["kakao_account"]["is_email_valid"]
|
41
|
+
hash[:email] = raw_info["kakao_account"]["email"]
|
42
|
+
end
|
43
|
+
hash
|
44
|
+
end
|
45
|
+
|
46
|
+
extra do
|
47
|
+
OmniAuth.logger.send :debug, "extra >>>>>>>>>>"
|
48
|
+
{ raw_info: raw_info }
|
49
|
+
end
|
50
|
+
|
51
|
+
def callback_url
|
52
|
+
options.redirect_url || (full_host + callback_path)
|
53
|
+
end
|
54
|
+
|
55
|
+
# def authorize_params
|
56
|
+
# options.authorize_params[:state] = SecureRandom.hex(24)
|
57
|
+
#
|
58
|
+
# if OmniAuth.config.test_mode
|
59
|
+
# @env ||= {}
|
60
|
+
# @env["rack.session"] ||= {}
|
61
|
+
# end
|
62
|
+
#
|
63
|
+
# params = options.authorize_params
|
64
|
+
# .merge(options_for("authorize"))
|
65
|
+
# .merge(pkce_authorize_params)
|
66
|
+
#
|
67
|
+
# params[:client_id] = options.client_id # client_id 추가
|
68
|
+
#
|
69
|
+
# session["omniauth.pkce.verifier"] = options.pkce_verifier if options.pkce
|
70
|
+
# session["omniauth.state"] = params[:state]
|
71
|
+
#
|
72
|
+
# params
|
73
|
+
# end
|
74
|
+
|
75
|
+
def auth_token_params
|
76
|
+
verifier = session.delete("omniauth.pkce.verifier")
|
77
|
+
params = {
|
78
|
+
code: request.params["code"],
|
79
|
+
client_id: options.client_id,
|
80
|
+
client_secret: options.client_secret,
|
81
|
+
redirect_uri: callback_url,
|
82
|
+
grant_type: "authorization_code"
|
83
|
+
}
|
84
|
+
params[:code_verifier] = verifier if verifier
|
85
|
+
params
|
86
|
+
end
|
87
|
+
|
88
|
+
def build_access_token
|
89
|
+
verifier = request.params["code"]
|
90
|
+
token = client.auth_code.get_token(verifier, {
|
91
|
+
redirect_uri: callback_url,
|
92
|
+
client_id: options.client_id,
|
93
|
+
# client_secret: options.client_secret
|
94
|
+
}.merge(token_params.to_hash(symbolize_keys: true)), deep_symbolize(options.auth_token_params))
|
95
|
+
token
|
96
|
+
end
|
97
|
+
|
98
|
+
private
|
99
|
+
|
100
|
+
def raw_info
|
101
|
+
@raw_info ||= access_token.get(USER_INFO_URL).parsed
|
102
|
+
end
|
103
|
+
end
|
104
|
+
end
|
105
|
+
end
|
106
|
+
|
107
|
+
OmniAuth.config.add_camelization "kakao", "Kakao"
|
@@ -0,0 +1,33 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
$:.push File.expand_path("../lib", __FILE__)
|
3
|
+
require "sb-omniauth-kakao/version"
|
4
|
+
|
5
|
+
Gem::Specification.new do |spec|
|
6
|
+
spec.name = "sb-omniauth-kakao"
|
7
|
+
spec.version = Omniauth::Kakao::VERSION
|
8
|
+
spec.platform = Gem::Platform::RUBY
|
9
|
+
spec.authors = ["archmagece"]
|
10
|
+
spec.email = ["archmagece@userspec.noreply.github.com"]
|
11
|
+
|
12
|
+
spec.homepage = "https://github.com/ScriptonBasestar/sb-omniauth-kakao"
|
13
|
+
spec.summary = %q{OmniAuth strategy for Kakao}
|
14
|
+
spec.description = %q{OmniAuth strategy for Kakao(http://developerspec.kakao.com/)}
|
15
|
+
spec.license = "MIT"
|
16
|
+
|
17
|
+
spec.rubyforge_project = "sb-omniauth-kakao"
|
18
|
+
|
19
|
+
spec.files = `git ls-files`.split("\n")
|
20
|
+
spec.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
|
21
|
+
spec.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
|
22
|
+
spec.require_paths = ["lib"]
|
23
|
+
|
24
|
+
spec.add_dependency 'omniauth', '~> 1.9'
|
25
|
+
spec.add_dependency 'omniauth-oauth2', '~> 1.3'
|
26
|
+
|
27
|
+
spec.add_development_dependency "bundler", "~> 2.6"
|
28
|
+
spec.add_development_dependency "rake", "~> 13.0"
|
29
|
+
spec.add_development_dependency 'rspec', '~> 3.13'
|
30
|
+
spec.add_development_dependency 'guard-rspec', '~> 4.7'
|
31
|
+
spec.add_development_dependency 'fakeweb', '~> 1.3'
|
32
|
+
spec.add_development_dependency "minitest", "~> 5.25"
|
33
|
+
end
|
@@ -0,0 +1,193 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
require 'omniauth'
|
3
|
+
require 'sb-omniauth-kakao'
|
4
|
+
|
5
|
+
describe OmniAuth::Strategies::Kakao do
|
6
|
+
CLIENT_ID = '<<your-client-id>>'
|
7
|
+
SERVER_NAME = 'www.example.com'
|
8
|
+
|
9
|
+
before do
|
10
|
+
OmniAuth.config.logger.level = 5
|
11
|
+
end
|
12
|
+
|
13
|
+
def make_middleware(client_id, opts={})
|
14
|
+
app = ->(env) { [200, env, "app"] }
|
15
|
+
|
16
|
+
middleware = OmniAuth::Strategies::Kakao.new(app, opts)
|
17
|
+
middleware.tap do |middleware|
|
18
|
+
middleware.options.client_id = client_id
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
def make_request(url, opts={})
|
23
|
+
Rack::MockRequest.env_for(url, {
|
24
|
+
'rack.session' => {},
|
25
|
+
'SERVER_NAME' => SERVER_NAME,
|
26
|
+
}.merge(opts))
|
27
|
+
end
|
28
|
+
|
29
|
+
describe "GET /auth/kakao" do
|
30
|
+
it "should redirect to authorize page" do
|
31
|
+
request = make_request('/auth/kakao')
|
32
|
+
middleware = make_middleware(CLIENT_ID)
|
33
|
+
|
34
|
+
code, env = middleware.call(request)
|
35
|
+
|
36
|
+
code.should == 302
|
37
|
+
|
38
|
+
expect_url = <<-EXPECT
|
39
|
+
https://kauth.kakao.com/oauth/authorize
|
40
|
+
?client_id=#{CLIENT_ID}
|
41
|
+
&redirect_uri=http://#{SERVER_NAME}/oauth
|
42
|
+
&response_type=code
|
43
|
+
EXPECT
|
44
|
+
.gsub(/(\n|\t|\s)/, '')
|
45
|
+
|
46
|
+
actual_url = URI.decode(env['Location'].split("&state")[0])
|
47
|
+
|
48
|
+
actual_url.should == expect_url
|
49
|
+
end
|
50
|
+
|
51
|
+
it "should customize redirect path" do
|
52
|
+
request = make_request('/auth/kakao')
|
53
|
+
middleware = make_middleware(CLIENT_ID, redirect_path: '/auth/kakao/callback')
|
54
|
+
|
55
|
+
code, env = middleware.call(request)
|
56
|
+
|
57
|
+
code.should == 302
|
58
|
+
|
59
|
+
expect_url = <<-EXPECT
|
60
|
+
https://kauth.kakao.com/oauth/authorize
|
61
|
+
?client_id=#{CLIENT_ID}
|
62
|
+
&redirect_uri=http://#{SERVER_NAME}/auth/kakao/callback
|
63
|
+
&response_type=code
|
64
|
+
EXPECT
|
65
|
+
.gsub(/(\n|\t|\s)/, '')
|
66
|
+
|
67
|
+
actual_url = URI.decode(env['Location'].split("&state")[0])
|
68
|
+
|
69
|
+
actual_url.should == expect_url
|
70
|
+
end
|
71
|
+
end
|
72
|
+
|
73
|
+
describe "GET /oauth" do
|
74
|
+
CODE = "dummy-code"
|
75
|
+
STATE = "dummy-state"
|
76
|
+
ACCESS_TOKEN = "dummy-access-token"
|
77
|
+
REFRESH_TOKEN = "dummy-refresh-token"
|
78
|
+
|
79
|
+
before do
|
80
|
+
FakeWeb.register_uri(:post, "https://kauth.kakao.com/oauth/token",
|
81
|
+
:content_type => "application/json;charset=UTF-8",
|
82
|
+
:parameters => {
|
83
|
+
:grant_type => 'authorization_code',
|
84
|
+
:client_id => CLIENT_ID,
|
85
|
+
:redirect_uri => URI.encode("http://#{SERVER_NAME}/oauth"),
|
86
|
+
:code => CODE
|
87
|
+
},
|
88
|
+
:body => {
|
89
|
+
:access_token => ACCESS_TOKEN,
|
90
|
+
:token_type => "bearer",
|
91
|
+
:refresh_token => REFRESH_TOKEN,
|
92
|
+
:expires_in => 99999,
|
93
|
+
:scope => "Basic_Profile"
|
94
|
+
}.to_json
|
95
|
+
)
|
96
|
+
|
97
|
+
FakeWeb.register_uri(:get, "https://kapi.kakao.com/v1/user/me",
|
98
|
+
:content_type => "application/json;charset=UTF-8",
|
99
|
+
:"Authorization" => "Bearer #{ACCESS_TOKEN}",
|
100
|
+
:body => {
|
101
|
+
:id => 123456789,
|
102
|
+
:properties => {
|
103
|
+
:nickname => "John Doe",
|
104
|
+
:thumbnail_image => "http://xxx.kakao.com/.../aaa.jpg",
|
105
|
+
:profile_image => "http://xxx.kakao.com/.../bbb.jpg",
|
106
|
+
}
|
107
|
+
}.to_json
|
108
|
+
)
|
109
|
+
end
|
110
|
+
|
111
|
+
it "should request access token and user information" do
|
112
|
+
request = make_request("/oauth?code=#{CODE}&state=#{STATE}", {
|
113
|
+
'rack.session' => {
|
114
|
+
'omniauth.state' => STATE
|
115
|
+
},
|
116
|
+
})
|
117
|
+
|
118
|
+
middleware = make_middleware(CLIENT_ID)
|
119
|
+
|
120
|
+
code, env = middleware.call(request)
|
121
|
+
|
122
|
+
code.should == 200
|
123
|
+
|
124
|
+
response = env['omniauth.auth']
|
125
|
+
|
126
|
+
response.provider.should == "kakao"
|
127
|
+
response.uid.should == "123456789"
|
128
|
+
|
129
|
+
information = response.info
|
130
|
+
information.name.should == "John Doe"
|
131
|
+
information.image.should == "http://xxx.kakao.com/.../aaa.jpg"
|
132
|
+
|
133
|
+
credentials = response.credentials
|
134
|
+
credentials.token.should == ACCESS_TOKEN
|
135
|
+
credentials.refresh_token.should == REFRESH_TOKEN
|
136
|
+
|
137
|
+
properties = response.extra.properties
|
138
|
+
properties.nickname.should == "John Doe"
|
139
|
+
properties.thumbnail_image.should == "http://xxx.kakao.com/.../aaa.jpg"
|
140
|
+
properties.profile_image.should == "http://xxx.kakao.com/.../bbb.jpg"
|
141
|
+
end
|
142
|
+
end
|
143
|
+
|
144
|
+
context "test environment" do
|
145
|
+
before do
|
146
|
+
OmniAuth.config.test_mode = true
|
147
|
+
OmniAuth.config.add_mock(:kakao, {
|
148
|
+
provider: "kakao",
|
149
|
+
uid: "123456789",
|
150
|
+
info: {
|
151
|
+
name: "John Doe",
|
152
|
+
image: "http://xxx.kakao.com/.../aaa.jpg"
|
153
|
+
}
|
154
|
+
})
|
155
|
+
end
|
156
|
+
|
157
|
+
describe "GET /auth/kakao" do
|
158
|
+
it "should redirect to callback url (/auth/kakao/callback)" do
|
159
|
+
request = make_request("/auth/kakao")
|
160
|
+
middleware = make_middleware(CLIENT_ID)
|
161
|
+
code, env = middleware.call(request)
|
162
|
+
|
163
|
+
code.should == 302
|
164
|
+
|
165
|
+
actual_path = URI(env["Location"]).path
|
166
|
+
actual_path.should == "/auth/kakao/callback"
|
167
|
+
end
|
168
|
+
end
|
169
|
+
|
170
|
+
describe "GET /oauth" do
|
171
|
+
it "should request registered mock" do
|
172
|
+
request = make_request("/oauth")
|
173
|
+
middleware = make_middleware(CLIENT_ID)
|
174
|
+
code, env = middleware.call(request)
|
175
|
+
|
176
|
+
code.should == 200
|
177
|
+
|
178
|
+
response = env["omniauth.auth"]
|
179
|
+
|
180
|
+
response.provider.should == "kakao"
|
181
|
+
response.uid.should == "123456789"
|
182
|
+
|
183
|
+
information = response.info
|
184
|
+
information.name.should == "John Doe"
|
185
|
+
information.image.should == "http://xxx.kakao.com/.../aaa.jpg"
|
186
|
+
end
|
187
|
+
end
|
188
|
+
|
189
|
+
after do
|
190
|
+
OmniAuth.config.test_mode = false
|
191
|
+
end
|
192
|
+
end
|
193
|
+
end
|
data/spec/spec_helper.rb
ADDED
@@ -0,0 +1,23 @@
|
|
1
|
+
# This file was generated by the `rspec --init` command. Conventionally, all
|
2
|
+
# specs live under a `spec` directory, which RSpec adds to the `$LOAD_PATH`.
|
3
|
+
# Require this file using `require "spec_helper"` to ensure that it is only
|
4
|
+
# loaded once.
|
5
|
+
#
|
6
|
+
# See http://rubydoc.info/gems/rspec-core/RSpec/Core/Configuration
|
7
|
+
require 'fakeweb'
|
8
|
+
require 'json'
|
9
|
+
|
10
|
+
$:.unshift File.expand_path('..', __FILE__)
|
11
|
+
$:.unshift File.expand_path('../../lib', __FILE__)
|
12
|
+
|
13
|
+
RSpec.configure do |config|
|
14
|
+
config.treat_symbols_as_metadata_keys_with_true_values = true
|
15
|
+
config.run_all_when_everything_filtered = true
|
16
|
+
config.filter_run :focus
|
17
|
+
|
18
|
+
# Run specs in random order to surface order dependencies. If you find an
|
19
|
+
# order dependency and want to debug it, you can fix the order by providing
|
20
|
+
# the seed, which is printed after each run.
|
21
|
+
# --seed 1234
|
22
|
+
config.order = 'random'
|
23
|
+
end
|
metadata
ADDED
@@ -0,0 +1,172 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: sb-omniauth-kakao
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.3.0
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- archmagece
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2025-01-22 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: omniauth
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - "~>"
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '1.9'
|
20
|
+
type: :runtime
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - "~>"
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '1.9'
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: omniauth-oauth2
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - "~>"
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '1.3'
|
34
|
+
type: :runtime
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - "~>"
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '1.3'
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: bundler
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - "~>"
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: '2.6'
|
48
|
+
type: :development
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - "~>"
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '2.6'
|
55
|
+
- !ruby/object:Gem::Dependency
|
56
|
+
name: rake
|
57
|
+
requirement: !ruby/object:Gem::Requirement
|
58
|
+
requirements:
|
59
|
+
- - "~>"
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: '13.0'
|
62
|
+
type: :development
|
63
|
+
prerelease: false
|
64
|
+
version_requirements: !ruby/object:Gem::Requirement
|
65
|
+
requirements:
|
66
|
+
- - "~>"
|
67
|
+
- !ruby/object:Gem::Version
|
68
|
+
version: '13.0'
|
69
|
+
- !ruby/object:Gem::Dependency
|
70
|
+
name: rspec
|
71
|
+
requirement: !ruby/object:Gem::Requirement
|
72
|
+
requirements:
|
73
|
+
- - "~>"
|
74
|
+
- !ruby/object:Gem::Version
|
75
|
+
version: '3.13'
|
76
|
+
type: :development
|
77
|
+
prerelease: false
|
78
|
+
version_requirements: !ruby/object:Gem::Requirement
|
79
|
+
requirements:
|
80
|
+
- - "~>"
|
81
|
+
- !ruby/object:Gem::Version
|
82
|
+
version: '3.13'
|
83
|
+
- !ruby/object:Gem::Dependency
|
84
|
+
name: guard-rspec
|
85
|
+
requirement: !ruby/object:Gem::Requirement
|
86
|
+
requirements:
|
87
|
+
- - "~>"
|
88
|
+
- !ruby/object:Gem::Version
|
89
|
+
version: '4.7'
|
90
|
+
type: :development
|
91
|
+
prerelease: false
|
92
|
+
version_requirements: !ruby/object:Gem::Requirement
|
93
|
+
requirements:
|
94
|
+
- - "~>"
|
95
|
+
- !ruby/object:Gem::Version
|
96
|
+
version: '4.7'
|
97
|
+
- !ruby/object:Gem::Dependency
|
98
|
+
name: fakeweb
|
99
|
+
requirement: !ruby/object:Gem::Requirement
|
100
|
+
requirements:
|
101
|
+
- - "~>"
|
102
|
+
- !ruby/object:Gem::Version
|
103
|
+
version: '1.3'
|
104
|
+
type: :development
|
105
|
+
prerelease: false
|
106
|
+
version_requirements: !ruby/object:Gem::Requirement
|
107
|
+
requirements:
|
108
|
+
- - "~>"
|
109
|
+
- !ruby/object:Gem::Version
|
110
|
+
version: '1.3'
|
111
|
+
- !ruby/object:Gem::Dependency
|
112
|
+
name: minitest
|
113
|
+
requirement: !ruby/object:Gem::Requirement
|
114
|
+
requirements:
|
115
|
+
- - "~>"
|
116
|
+
- !ruby/object:Gem::Version
|
117
|
+
version: '5.25'
|
118
|
+
type: :development
|
119
|
+
prerelease: false
|
120
|
+
version_requirements: !ruby/object:Gem::Requirement
|
121
|
+
requirements:
|
122
|
+
- - "~>"
|
123
|
+
- !ruby/object:Gem::Version
|
124
|
+
version: '5.25'
|
125
|
+
description: OmniAuth strategy for Kakao(http://developerspec.kakao.com/)
|
126
|
+
email:
|
127
|
+
- archmagece@userspec.noreply.github.com
|
128
|
+
executables: []
|
129
|
+
extensions: []
|
130
|
+
extra_rdoc_files: []
|
131
|
+
files:
|
132
|
+
- ".github/workflows/gem-push.yml"
|
133
|
+
- ".gitignore"
|
134
|
+
- ".rspec"
|
135
|
+
- Gemfile
|
136
|
+
- Guardfile
|
137
|
+
- README.md
|
138
|
+
- Rakefile
|
139
|
+
- example/.env.sample
|
140
|
+
- example/Gemfile
|
141
|
+
- example/Makefile
|
142
|
+
- example/config.ru
|
143
|
+
- lib/omniauth/strategies/kakao.rb
|
144
|
+
- lib/sb-omniauth-kakao.rb
|
145
|
+
- lib/sb-omniauth-kakao/version.rb
|
146
|
+
- sb-omniauth-kakao.gemspec
|
147
|
+
- spec/omniauth/strategies/kakao_spec.rb
|
148
|
+
- spec/spec_helper.rb
|
149
|
+
homepage: https://github.com/ScriptonBasestar/sb-omniauth-kakao
|
150
|
+
licenses:
|
151
|
+
- MIT
|
152
|
+
metadata: {}
|
153
|
+
post_install_message:
|
154
|
+
rdoc_options: []
|
155
|
+
require_paths:
|
156
|
+
- lib
|
157
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
158
|
+
requirements:
|
159
|
+
- - ">="
|
160
|
+
- !ruby/object:Gem::Version
|
161
|
+
version: '0'
|
162
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
163
|
+
requirements:
|
164
|
+
- - ">="
|
165
|
+
- !ruby/object:Gem::Version
|
166
|
+
version: '0'
|
167
|
+
requirements: []
|
168
|
+
rubygems_version: 3.5.22
|
169
|
+
signing_key:
|
170
|
+
specification_version: 4
|
171
|
+
summary: OmniAuth strategy for Kakao
|
172
|
+
test_files: []
|