opro 0.4.0 → 0.4.1
Sign up to get free protection for your applications and to get access to all the features.
- data/.travis.yml +1 -0
- data/CHANGELOG.md +13 -0
- data/Gemfile +6 -22
- data/Gemfile.lock +13 -9
- data/README.md +48 -34
- data/Rakefile +2 -2
- data/VERSION +1 -1
- data/app/controllers/opro/oauth/client_app_controller.rb +19 -1
- data/app/controllers/opro/oauth/docs_controller.rb +21 -11
- data/app/controllers/opro/oauth/tests_controller.rb +6 -6
- data/app/models/opro/oauth/auth_grant.rb +6 -4
- data/app/views/opro/oauth/auth/new.html.erb +21 -22
- data/app/views/opro/oauth/client_app/edit.html.erb +14 -0
- data/app/views/opro/oauth/client_app/index.html.erb +17 -16
- data/app/views/opro/oauth/client_app/new.html.erb +19 -13
- data/app/views/opro/oauth/client_app/show.html.erb +15 -0
- data/app/views/opro/oauth/docs/index.html.erb +20 -21
- data/app/views/opro/oauth/docs/markdown/curl.md.erb +10 -10
- data/app/views/opro/oauth/docs/markdown/oauth.md.erb +6 -6
- data/app/views/opro/oauth/docs/markdown/password_exchange.md.erb +9 -9
- data/app/views/opro/oauth/docs/markdown/permissions.md.erb +1 -1
- data/app/views/opro/oauth/docs/markdown/quick_start.md.erb +21 -21
- data/app/views/opro/oauth/docs/markdown/refresh_tokens.md.erb +4 -4
- data/app/views/opro/oauth/docs/show.html.erb +4 -2
- data/app/views/opro/oauth/tests/index.html.erb +7 -7
- data/lib/generators/opro/install_generator.rb +1 -1
- data/lib/opro.rb +6 -6
- data/lib/opro/controllers/concerns/error_messages.rb +3 -3
- data/lib/opro/controllers/concerns/permissions.rb +1 -1
- data/lib/opro/rails/routes.rb +12 -3
- data/opro.gemspec +15 -17
- data/test/integration/client_app_controller_test.rb +28 -1
- data/test/integration/docs_controller_test.rb +1 -0
- data/test/models/opro/oauth/auth_grant_test.rb +7 -0
- data/test/test_helper.rb +6 -3
- metadata +91 -41
- data/app/views/opro/oauth/client_app/create.html.erb +0 -15
@@ -8,9 +8,9 @@ class Opro::Oauth::TestsController < OproController
|
|
8
8
|
|
9
9
|
def show
|
10
10
|
result = if valid_oauth?
|
11
|
-
{:status => 200, :message => 'OAuth
|
11
|
+
{:status => 200, :message => 'OAuth worked!', :params => params, :user_id => oauth_user.id }
|
12
12
|
else
|
13
|
-
{:status => :unauthorized, :message => "OAuth
|
13
|
+
{:status => :unauthorized, :message => "OAuth did not work :( #{generate_oauth_error_message!}", :params => params}
|
14
14
|
end
|
15
15
|
|
16
16
|
respond_to do |format|
|
@@ -25,9 +25,9 @@ class Opro::Oauth::TestsController < OproController
|
|
25
25
|
|
26
26
|
def create
|
27
27
|
result = if valid_oauth?
|
28
|
-
{:status => 200, :message => 'OAuth
|
28
|
+
{:status => 200, :message => 'OAuth worked!', :params => params, :user_id => oauth_user.id }
|
29
29
|
else
|
30
|
-
{:status => :unauthorized, :message => "OAuth
|
30
|
+
{:status => :unauthorized, :message => "OAuth did not work :( #{generate_oauth_error_message!}", :params => params}
|
31
31
|
end
|
32
32
|
|
33
33
|
respond_to do |format|
|
@@ -42,9 +42,9 @@ class Opro::Oauth::TestsController < OproController
|
|
42
42
|
|
43
43
|
def destroy
|
44
44
|
result = if valid_oauth?
|
45
|
-
{:status => 200, :message => '
|
45
|
+
{:status => 200, :message => 'OH NO!!! OAuth is disabled on this action; this is bad', :params => params}
|
46
46
|
else
|
47
|
-
{:status => :unauthorized, :message => "
|
47
|
+
{:status => :unauthorized, :message => "OAuth is disabled on this action; this is the correct result!", :params => params}
|
48
48
|
end
|
49
49
|
|
50
50
|
respond_to do |format|
|
@@ -8,7 +8,7 @@ class Opro::Oauth::AuthGrant < ActiveRecord::Base
|
|
8
8
|
belongs_to :client_app, :class_name => "Opro::Oauth::ClientApp", :foreign_key => "application_id"
|
9
9
|
|
10
10
|
|
11
|
-
validates :application_id, :uniqueness => {:scope => :user_id, :message => "Application is already
|
11
|
+
validates :application_id, :uniqueness => {:scope => :user_id, :message => "Application is already authorized for this user"}, :presence => true
|
12
12
|
validates :code, :uniqueness => true
|
13
13
|
validates :access_token, :uniqueness => true
|
14
14
|
|
@@ -26,7 +26,7 @@ class Opro::Oauth::AuthGrant < ActiveRecord::Base
|
|
26
26
|
|
27
27
|
def expired?
|
28
28
|
return false unless ::Opro.require_refresh_within.present?
|
29
|
-
return expires_in < 0
|
29
|
+
return expires_in && expires_in < 0
|
30
30
|
end
|
31
31
|
|
32
32
|
def not_expired?
|
@@ -80,13 +80,15 @@ class Opro::Oauth::AuthGrant < ActiveRecord::Base
|
|
80
80
|
end
|
81
81
|
|
82
82
|
def generate_tokens!
|
83
|
-
self.code
|
83
|
+
self.code = unique_token_for(:code)
|
84
|
+
self.access_token = unique_token_for(:access_token)
|
85
|
+
self.refresh_token = unique_token_for(:refresh_token)
|
84
86
|
end
|
85
87
|
|
86
88
|
# used to guarantee that we are generating unique codes, access_tokens and refresh_tokens
|
87
89
|
def unique_token_for(field, secure_token = SecureRandom.hex(16))
|
88
90
|
raise "bad field" unless self.respond_to?(field)
|
89
|
-
auth_grant = self.class.where(field => secure_token).first
|
91
|
+
auth_grant = self.class.where(field => secure_token).first
|
90
92
|
return secure_token if auth_grant.blank?
|
91
93
|
unique_token_for(field)
|
92
94
|
end
|
@@ -1,28 +1,27 @@
|
|
1
|
-
<
|
1
|
+
<div class="opro">
|
2
|
+
<h2>Authorization Request</h2>
|
2
3
|
|
4
|
+
<p>
|
5
|
+
<%= @client_app.name %> would like to access your data. Only accept if you trust this application. You will then be redirected back to: "<%= @redirect_uri %>".
|
6
|
+
</p>
|
3
7
|
|
4
|
-
|
5
|
-
<%= @client_app.name %> would like to access your Data. Only accept if you know them, you will then be redirected back to: "<%= @redirect_uri %>".
|
6
|
-
</p>
|
8
|
+
<%= form_for @client_app, :url => oauth_authorize_path(:client_id => @client_app.client_id, :redirect_uri => @redirect_uri), :method => :post do |f| %>
|
7
9
|
|
8
|
-
|
10
|
+
I Authorize <%= @client_app.name %> to:
|
9
11
|
|
12
|
+
<ul>
|
13
|
+
<li><%= check_box_tag 'permissions[read]', 1, true, {:disabled => true} %> Read</li>
|
14
|
+
<% @scopes.each do |permission| %>
|
15
|
+
<% is_checked = @client_app.permissions.key?(permission) ? @client_app.permissions[permission] : true %>
|
16
|
+
<li>
|
17
|
+
<%= check_box_tag "permissions[#{permission}]", 1, is_checked %>
|
18
|
+
<%= permission.capitalize %>
|
19
|
+
</li>
|
20
|
+
<% end %>
|
21
|
+
</ul>
|
10
22
|
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
<ul>
|
15
|
-
|
16
|
-
<li><%= check_box_tag 'permissions[read]', 1, true, {:disabled => true} %> Read</li>
|
17
|
-
|
18
|
-
<% @scopes.each do |permission| %>
|
19
|
-
<% is_checked = @client_app.permissions.key?(permission) ? @client_app.permissions[permission] : true %>
|
20
|
-
<li><%= check_box_tag "permissions[#{permission}]", 1, is_checked %> <%= permission.capitalize %></li>
|
21
|
-
<% end %>
|
22
|
-
</ul>
|
23
|
-
|
24
|
-
<%= f.submit 'Authorize This Application', :id => 'oauthAuthorize' %>
|
25
|
-
<%- end -%>
|
26
|
-
|
27
|
-
<%= button_to 'Decline this Request', request.referrer||'/', :id => 'oauthNoAuthorize' %>
|
23
|
+
<%= f.submit 'Authorize This Application', :id => 'oauthAuthorize' %>
|
24
|
+
<%- end -%>
|
28
25
|
|
26
|
+
<%= button_to 'Decline this Request', request.referrer||'/', :id => 'oauthNoAuthorize' %>
|
27
|
+
</div>
|
@@ -0,0 +1,14 @@
|
|
1
|
+
<div class="opro">
|
2
|
+
<h2>Edit your OAuth Client App</h2>
|
3
|
+
<ul>
|
4
|
+
<% @client_app.errors.full_messages.each do |msg| %>
|
5
|
+
<li><%= msg %></li>
|
6
|
+
<% end %>
|
7
|
+
</ul>
|
8
|
+
|
9
|
+
<%= form_for @client_app, :url => oauth_client_app_path(@client_app), :method => :put do |f| %>
|
10
|
+
<%= f.label :name %>
|
11
|
+
<%= f.text_field :name, :placeholder => 'App Name' %>
|
12
|
+
<%= f.submit 'Update your Client', :id => 'submitApp' %>
|
13
|
+
<%- end -%>
|
14
|
+
</div>
|
@@ -1,18 +1,19 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
<
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
1
|
+
<div class="opro">
|
2
|
+
<%- if @client_apps.blank? -%>
|
3
|
+
<h2>You have no applications.</h2>
|
4
|
+
<%- else -%>
|
5
|
+
<h2>Your Applications</h2>
|
6
|
+
<% @client_apps.each do |client_app| %>
|
7
|
+
<table>
|
8
|
+
<tr><td>Name: </td><td> <%= client_app.name %></td></tr>
|
9
|
+
<tr><td>Client Id: </td><td> <%= client_app.app_id %></td></tr>
|
10
|
+
<tr><td>Client Secret: </td><td> <%= client_app.app_secret %></td></tr>
|
11
|
+
</table>
|
12
|
+
<%= link_to "edit", edit_oauth_client_app_path(client_app) %>
|
13
|
+
<hr />
|
14
|
+
<%- end -%>
|
12
15
|
<%- end -%>
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
<div>
|
17
|
-
<%= link_to 'Register an New App', new_oauth_client_app_path %>
|
16
|
+
<div>
|
17
|
+
<%= link_to 'Register a new application', new_oauth_client_app_path %>
|
18
|
+
</div>
|
18
19
|
</div>
|
@@ -1,14 +1,20 @@
|
|
1
|
-
<
|
2
|
-
<
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
1
|
+
<div class="opro">
|
2
|
+
<h2>Create An OAuth Client Application</h2>
|
3
|
+
<ul>
|
4
|
+
<% @client_app.errors.full_messages.each do |msg| %>
|
5
|
+
<li><%= msg %></li>
|
6
|
+
<% end %>
|
7
|
+
</ul>
|
8
|
+
<div>
|
9
|
+
<%= form_for @client_app, :url => oauth_client_apps_path do |f| %>
|
10
|
+
<%= f.label :name %>
|
11
|
+
<%= f.text_field :name, :placeholder => 'Application Name' %>
|
12
|
+
<%= f.submit 'Create OAuth Client Application', :id => 'submitApp' %>
|
13
|
+
<p>(you can change this name later)</p>
|
14
|
+
<%- end -%>
|
15
|
+
</div>
|
10
16
|
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
</div>
|
17
|
+
<div>
|
18
|
+
<%= link_to 'My Applications', oauth_client_apps_path %>
|
19
|
+
</div>
|
20
|
+
</div>
|
@@ -0,0 +1,15 @@
|
|
1
|
+
<div class="opro">
|
2
|
+
<p>Copy these credentials down for use in your application</p>
|
3
|
+
<table>
|
4
|
+
<tr><td>Name: </td><td><%= @client_app.name %></td></tr>
|
5
|
+
<tr><td>Client Id: </td><td><%= @client_app.app_id %></td></tr>
|
6
|
+
<tr><td>Secret: </td><td><%= @client_app.app_secret %></td></tr>
|
7
|
+
</table>
|
8
|
+
<%= link_to "edit", edit_oauth_client_app_path(@client_app) %>
|
9
|
+
<hr />
|
10
|
+
<p>
|
11
|
+
Read the
|
12
|
+
<%= link_to 'Quick Start Documentation', oauth_doc_path(:quick_start) %> or
|
13
|
+
<%= link_to 'Register Another OAuth Client App', new_oauth_client_app_path %>
|
14
|
+
</p>
|
15
|
+
</div>
|
@@ -1,27 +1,26 @@
|
|
1
|
-
<
|
1
|
+
<div class="opro">
|
2
|
+
<h2>OAuth Docs</h2>
|
3
|
+
<p>OAuth shouldn't be hard, and neither should docs</p>
|
2
4
|
|
5
|
+
<h2>Quick Links</h2>
|
6
|
+
<ul>
|
7
|
+
<li><%= link_to 'Quick Start', oauth_doc_path(:quick_start) %></li>
|
8
|
+
<li><%= link_to 'Curl', oauth_doc_path(:curl) %></li>
|
9
|
+
<li><%= link_to 'OAuth', oauth_doc_path(:oauth) %></li>
|
3
10
|
|
4
|
-
|
11
|
+
<% if ::Opro.request_permissions.present? %>
|
12
|
+
<li><%= link_to 'Permisions', oauth_doc_path(:permissions) %></li>
|
13
|
+
<% end %>
|
5
14
|
|
6
|
-
|
15
|
+
<% if ::Opro.require_refresh_within.present? %>
|
16
|
+
<li><%= link_to 'Refresh Tokens', oauth_doc_path(:refresh_tokens) %></li>
|
17
|
+
<% end %>
|
7
18
|
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
<li><%= link_to 'Oauth', oauth_doc_path(:oauth) %></li>
|
19
|
+
<% if ::Opro.password_exchange_enabled? %>
|
20
|
+
<li><%= link_to 'Password Exchange', oauth_doc_path(:password_exchange) %></li>
|
21
|
+
<% end %>
|
12
22
|
|
13
|
-
|
14
|
-
<li><%= link_to 'Permisions', oauth_doc_path(:permissions) %></li>
|
15
|
-
<% end %>
|
23
|
+
</ul>
|
16
24
|
|
17
|
-
|
18
|
-
|
19
|
-
<% end %>
|
20
|
-
|
21
|
-
<% if ::Opro.password_exchange_enabled? %>
|
22
|
-
<li><%= link_to 'Password Exchange', oauth_doc_path(:password_exchange) %></li>
|
23
|
-
<% end %>
|
24
|
-
|
25
|
-
</ul>
|
26
|
-
|
27
|
-
<%= render_doc(:quick_start) %>
|
25
|
+
<%= render_doc(:quick_start) %>
|
26
|
+
</div>
|
@@ -1,29 +1,29 @@
|
|
1
1
|
# Curl
|
2
2
|
|
3
|
-
[Curl](http://curl.haxx.se/) is a command line tool for transferring data with a url syntax. Most systems should have curl installed. Open up terminal on OS X or command prompt on
|
3
|
+
[Curl](http://curl.haxx.se/) is a command line tool for transferring data with a url syntax. Most systems should have curl installed. Open up terminal on OS X or command prompt on Windows and type in `curl`. There are parts of the OAuth process that were not intended for direct human interaction, such as exchanging the code from the Provider for an access_token. Because of this, it can be easier to use `curl` to talk to a server directly instead of using a web browser.
|
4
4
|
|
5
5
|
## What is it good for?
|
6
6
|
|
7
|
-
With curl we're able to arbitrarily add parameters to our requests and
|
7
|
+
With curl, we're able to arbitrarily add parameters to our requests and send using arbitrary HTTP verbs (GET/POST/DELETE) that are difficult to simulate in the browser. If you need to `POST` data to a url, doing so with curl is much easier than constructing a form for testing.
|
8
8
|
|
9
9
|
# Hurl
|
10
10
|
|
11
|
-
[Hurl](http://hurl.it/) is an open
|
11
|
+
[Hurl](http://hurl.it/) is an open source browser-based `curl` implementation. If you're going to do quite a few curl requests, using it can be easier than the command line.
|
12
12
|
|
13
13
|
## How do I use it?
|
14
14
|
|
15
|
-
On the command line you should be able to get get help by typing `man curl` if your system supports man pages. Below are some simple and common use cases
|
15
|
+
On the command line, you should be able to get get help by typing `man curl` if your system supports man pages. Below are some simple and common use cases.
|
16
16
|
|
17
17
|
### Get Webpage
|
18
18
|
|
19
|
-
You can get the entire contents of a web document by simply
|
19
|
+
You can get the entire contents of a web document by simply calling curl with that url:
|
20
20
|
|
21
21
|
$ curl https://www.google.com
|
22
22
|
|
23
23
|
### Get Headers
|
24
24
|
|
25
25
|
|
26
|
-
You can ask for the headers of a request by adding the `-I` flag to a curl command
|
26
|
+
You can ask for the headers of a request by adding the `-I` flag to a curl command:
|
27
27
|
|
28
28
|
$ curl https://www.google.com -I
|
29
29
|
HTTP/1.1 200 OK
|
@@ -37,15 +37,15 @@ You can ask for the headers of a request by adding the `-I` flag to a curl comma
|
|
37
37
|
|
38
38
|
### Set Headers
|
39
39
|
|
40
|
-
You can set a request header by using `-H
|
40
|
+
You can set a request header by using `-H`. For example, if you wanted to send an access_token in a header, you could issue this request (assuming your access token is '9693accessTokena7ca570bbaf'):
|
41
41
|
|
42
|
-
$ curl -H "Authorization: token 9693accessTokena7ca570bbaf" "<%= oauth_test_url(:show_me_the_money, :protocol => @protocol)%>"
|
42
|
+
$ curl -H "Authorization: token 9693accessTokena7ca570bbaf" "<%= oauth_test_url(:show_me_the_money, :protocol => @protocol) %>"
|
43
43
|
|
44
44
|
|
45
45
|
### HTTP Verb
|
46
46
|
|
47
|
-
You can specify the type of request you make in curl (GET, POST, PUT, DELETE, etc.) by using `-X`. For example if you wanted to POST to the /products
|
47
|
+
You can specify the type of request you make in curl (GET, POST, PUT, DELETE, etc.) by using `-X`. For example, if you wanted to POST to the /products path at <%= root_url %>, you could do so like this:
|
48
48
|
|
49
|
-
$ curl -X POST <%= root_url %>
|
49
|
+
$ curl -X POST <%= root_url %>products
|
50
50
|
|
51
51
|
|
@@ -1,13 +1,13 @@
|
|
1
1
|
## OAuth 2
|
2
2
|
|
3
|
-
OAuth comes in a few different flavors
|
3
|
+
OAuth comes in a few different flavors. This implementation of OAuth comes from [Version 22 of the OAuth 2.0 protocol](http://tools.ietf.org/html/draft-ietf-oauth-v2-22) and is heavily influenced by [Facebook's Server Side OAuth Authentication](http://developers.facebook.com/docs/authentication/server-side/) and [Github's API](http://developer.github.com/v3/oauth/).
|
4
4
|
|
5
5
|
|
6
6
|
## What is OAuth?
|
7
7
|
|
8
8
|
OAuth is a secure way to grant authorization without having to transfer passwords to third parties. If you've used an iPhone or Android app to access Twitter or Facebook you've likely used OAuth.
|
9
9
|
|
10
|
-
The flow is simple
|
10
|
+
The flow is simple: it is started when a user clicks on an authorization button. They are then directed to the OAuth provider's website, such as Facebook. They are then prompted to confirm with the OAuth provider that they are who they say they are by logging in. The user is then given the opportunity to grant authorization to the OAuth client (where the request was initiated, such as an iPhone app). After returning to the client, a code is sent that can be exchanged for a secure token. This secure token can be used to authenticate as the user. This way an iPhone app can ask for personalized content to show to the user, such as a friend list or messages. This is the mechanism that drives most of the web.
|
11
11
|
|
12
12
|
|
13
13
|
## Watch "OAuth: A Tale of 2 Servers"
|
@@ -19,18 +19,18 @@ This video covers a typical flow an OAuth client follows with an OAuth provider
|
|
19
19
|
|
20
20
|
## Not just Mobile
|
21
21
|
|
22
|
-
Client and server side web applications can use this type of authorization to add features to their service such as posting things to a timeline
|
22
|
+
Client and server side web applications can use this type of authorization to add features to their service such as posting things to a timeline or adding personalization.
|
23
23
|
|
24
24
|
|
25
25
|
## Alternatives
|
26
26
|
|
27
|
-
OAuth is simple in concept, but can be tricky to implement right. Many services also support basic auth. With basic auth you send a user's username and password along with every request. While this is fairly simple it means that the client application
|
27
|
+
OAuth is simple in concept, but can be tricky to implement right. Many services also support basic auth. With basic auth, you send a user's username and password along with every request. While this is fairly simple, it means that the client application stores your password, and this is not very secure.
|
28
28
|
|
29
29
|
|
30
30
|
## Clients
|
31
31
|
|
32
|
-
This website is an OAuth
|
32
|
+
This website is an OAuth provider, and you can create an OAuth client to access this website as a logged in user for select URLs.
|
33
33
|
|
34
|
-
To get started getting your first OAuth token follow the <%= view_context.link_to '
|
34
|
+
To get started with getting your first OAuth token, follow the <%= view_context.link_to 'Quick Start Guide', oauth_doc_path(:quick_start) %>.
|
35
35
|
|
36
36
|
|
@@ -3,12 +3,12 @@
|
|
3
3
|
|
4
4
|
## Password Exchange
|
5
5
|
|
6
|
-
If you're building a mobile (iPhone, Android, etc.) app it can be easier to exchange a user's password and email/username for an access token
|
6
|
+
If you're building a mobile (iPhone, Android, etc.) app, it can be easier to exchange a user's password and email/username for an access token than to send your user through the traditional OAuth flow.
|
7
7
|
|
8
8
|
|
9
9
|
## Step 1: Register your Application
|
10
10
|
|
11
|
-
Sign in as a registered user then visit the [new client application page](/oauth_client_apps/new). Enter in the name of your application
|
11
|
+
Sign in as a registered user then visit the [new client application page](/oauth_client_apps/new). Enter in the name of your application. For this example, we can use `foo`; you can change this later if you desire. Hit enter and you should see a screen that has your application name along with a `client id` and a `secret`. These behave like a username and password for your OAuth application.
|
12
12
|
|
13
13
|
|
14
14
|
Name: foo
|
@@ -16,30 +16,30 @@ Sign in as a registered user then visit the [new client application page](/oauth
|
|
16
16
|
client Secret: 14321myClientSecret8765
|
17
17
|
|
18
18
|
|
19
|
-
Once you've registered an app successfully we can start to build an OAuth application. Don't continue until you've [registered a client app](/oauth_client_apps/new).
|
19
|
+
Once you've registered an app successfully, we can start to build an OAuth application. Don't continue until you've [registered a client app](/oauth_client_apps/new).
|
20
20
|
|
21
21
|
**Note:** Replace the client id and secret with your actual client id and secret.
|
22
22
|
|
23
|
-
Once you have your id and secret, you can ask the user of your application to provide you with their username and password. For the purposes of this we will be using the
|
23
|
+
Once you have your id and secret, you can ask the user of your application to provide you with their username and password. For the purposes of this example we will be using the email address `foo@example.com` and password `p4ssw0rd`.
|
24
24
|
|
25
25
|
**Note:** Replace the email and password with a real user's credentials.
|
26
26
|
|
27
27
|
|
28
|
-
Once you have the email/username and password of a user, you can exchange this information for a token by sending the server your client\_id & client\_secret along with username and password. Don't forget to url encode any special characters like `@`, and always transmit this sensitive data using a secure protocol (such as https):
|
28
|
+
Once you have the email/username and password of a user, you can exchange this information for a token by sending the server your client\_id & client\_secret along with the username and password. Don't forget to url encode any special characters like `@`, and always transmit this sensitive data using a secure protocol (such as https):
|
29
29
|
|
30
30
|
<%= oauth_token_url(:protocol => @protocol, :email => "foo@example.com", :password => "p4ssw0rd", :client_id => "3234myClientId5678", :client_secret => "14321myClientSecret8765" ) %>
|
31
31
|
|
32
|
-
The response should be
|
32
|
+
The response should be JSON with an access_token:
|
33
33
|
|
34
34
|
|
35
35
|
{"access_token":"9693accessTokena7ca570bbaf","refresh_token":"3a3c129ad02b573de78e65af06c293f1","expires_in":null}
|
36
36
|
|
37
|
-
You can now use the `access_token` in the parameters of future requests
|
37
|
+
You can now use the `access_token` in the parameters or the header of future requests. See the end of the <%= view_context.link_to 'Quick Start Guide', oauth_doc_path(:quick_start) %> for examples.
|
38
38
|
|
39
39
|
|
40
40
|
## Additional Exchange
|
41
41
|
|
42
42
|
|
43
|
-
In addition to username/password the owner of this web service may choose to implement other custom exchanges such as Facebook or Twitter token exchange for an access token. You must contact the owner of this web service to see if they support other data when exchanging tokens.
|
43
|
+
In addition to username/password, the owner of this web service may choose to implement other custom exchanges such as Facebook or Twitter token exchange for an access token. You must contact the owner of this web service to see if they support other data when exchanging tokens.
|
44
44
|
|
45
|
-
When you do this make sure to pass `grant_type=password` or `grant_type=bearer` in the request to
|
45
|
+
When you do this make sure to pass `grant_type=password` or `grant_type=bearer` in the request to `<%= oauth_token_url %>` in addition to any required parameters.
|
@@ -16,7 +16,7 @@ To perform any type of request other than a [GET](http://en.wikipedia.org/wiki/H
|
|
16
16
|
|
17
17
|
## Request Scope
|
18
18
|
|
19
|
-
As a client application you can request specific scopes while you are authorizing a user
|
19
|
+
As a client application, you can request specific scopes while you are authorizing a user. If no scope is specified, all permissions will be requested. This is an example of an application with client id of `3234myClientId5678` specifying that they want `write` access for their app:
|
20
20
|
|
21
21
|
|
22
22
|
<%= oauth_authorize_url(:client_id => "3234myClientId5678", :protocol => @protocol) + "&scope[]=write" %>
|
@@ -1,6 +1,6 @@
|
|
1
1
|
## Quick Start Guide
|
2
2
|
|
3
|
-
This site is providing OAuth 2 through [
|
3
|
+
This site is providing OAuth 2 through [oPRO](http://github.com/schneems/opro). If this is your first time using OAuth, please visit [What is OAuth](<%= oauth_doc_path(:oauth) %>) or follow along with this guide.
|
4
4
|
|
5
5
|
<% if ::Opro.password_exchange_enabled? %>
|
6
6
|
|
@@ -13,42 +13,42 @@ If you are building a client application and have direct access to a user's cred
|
|
13
13
|
# OAuth 2 Flow
|
14
14
|
|
15
15
|
|
16
|
-
## Step 1: Register your
|
16
|
+
## Step 1: Register your application
|
17
17
|
|
18
|
-
Sign in as a registered user then visit the [new client application page](
|
18
|
+
Sign in as a registered user then visit the [new client application page](<%= new_oauth_client_app_path %>). Enter in the name of your application. For this example, we will use `foo`; you can change this later if you desire. Hit enter and you should see a screen that has your application name along with a `client id` and a `secret`. These behave like a username and password for your OAuth application.
|
19
19
|
|
20
20
|
|
21
21
|
Name: foo
|
22
|
-
|
22
|
+
Client id: 3234myClientId5678
|
23
23
|
Secret: 14321myClientSecret8765
|
24
24
|
|
25
25
|
|
26
|
-
Once you've registered an app successfully we can start to build an OAuth application. Don't continue until you've [registered a client app](
|
26
|
+
Once you've registered an app successfully we can start to build an OAuth application. Don't continue until you've [registered a client app](<%= new_oauth_client_app_path %>).
|
27
27
|
|
28
28
|
|
29
|
-
## Step 2: As a
|
29
|
+
## Step 2: As a user, grant access to your app
|
30
30
|
|
31
|
-
Now that you have a client application, you'll want to give it access to a user account. Open a new browser window
|
31
|
+
Now that you have a client application, you'll want to give it access to a user account. Open a new browser window and log in with a user account, then give your application permission by visiting the url below (swap out '3234myClientId5678' for your client id and '14321myClientSecret8765' for your client secret)
|
32
32
|
|
33
33
|
<%= oauth_authorize_url(:protocol => @protocol, :redirect_uri => "/", :client_id => "3234myClientId5678", :client_secret => "14321myClientSecret8765" ) %>
|
34
34
|
|
35
35
|
|
36
36
|
This should land you on a page asking if you would like to grant permission to the application. If not, make sure you're logged in and you put the correct client id in the url.
|
37
37
|
|
38
|
-
Once you grant your application permission, you will be redirected back to the url provided. In this case we will go back to the home page of
|
38
|
+
Once you grant your application permission, you will be redirected back to the url provided. In this case, we will go back to the home page of this app.
|
39
39
|
|
40
|
-
Once redirected to the home page, take a look in the address bar
|
40
|
+
Once redirected to the home page, take a look in the address bar. We should see a `code` parameter. Copy this for use later:
|
41
41
|
|
42
42
|
<%= root_url(:protocol => @protocol) + "?code=4857goldfish827423" %>
|
43
43
|
|
44
|
-
In the url above the `code` would be `4857goldfish827423`. This code can be used to obtain an access token for the user. Once you have a user's access token, you can perform actions for the user as if they were logged in. If you accidentally close this page, don't worry just visit first url and
|
44
|
+
In the url above, the `code` would be `4857goldfish827423`. This code can be used to obtain an access token for the user. Once you have a user's access token, you can perform actions for the user as if they were logged in. If you accidentally close this page, don't worry-- just visit the first url in Step 2 again and the application will show you the code again.
|
45
45
|
|
46
46
|
|
47
|
-
## Step 3: Get an
|
47
|
+
## Step 3: Get an access token for a user with curl
|
48
48
|
|
49
|
-
We'll be using [Curl](<%= oauth_doc_path(:curl) %>) to go through the process of getting an access for our first user
|
49
|
+
We'll be using [Curl](<%= oauth_doc_path(:curl) %>) to go through the process of getting an access token for our first user. You'll likely use http client libraries in your actual application, but most systems come with curl, and it is a fairly easy way to get started. If you've never used it before, read our [curl documentation](<%= oauth_doc_path(:curl) %>)
|
50
50
|
|
51
|
-
(Note in all code examples the $ character indicates we are on the command line, it does not need to be
|
51
|
+
(Note in all code examples the $ character indicates we are on the command line, it does not need to be copied)
|
52
52
|
|
53
53
|
You'll want to make sure to replace `client_id`, `client_secret`, and `code` with your values.
|
54
54
|
|
@@ -59,29 +59,29 @@ You'll want to make sure to replace `client_id`, `client_secret`, and `code` wit
|
|
59
59
|
:code => "4857goldfish827423") %>'
|
60
60
|
|
61
61
|
|
62
|
-
You should get back a response that looks like this
|
62
|
+
You should get back a response that looks like this:
|
63
63
|
|
64
64
|
$ {"access_token":"9693accessTokena7ca570bbaf","refresh_token":"3a3c129ad02b573de78e65af06c293f1","expires_in":null}
|
65
65
|
|
66
66
|
|
67
|
-
If not, double check the previous steps and ensure you are using the correct values in the query. Once you get a successful response, copy the `access_token` for use later
|
67
|
+
If not, double check the previous steps and ensure you are using the correct values in the query. Once you get a successful response, copy the `access_token` for use later. In this example, it is `9693accessTokena7ca570bbaf`. Treat this access_token as if it were the user's password. It is sensitive information.
|
68
68
|
|
69
69
|
|
70
70
|
## Step 4: Use the access token
|
71
71
|
|
72
|
-
Now we've gone through all the hard work of getting an access token, you can use it to make authenticated requests to the server.
|
72
|
+
Now that we've gone through all the hard work of getting an access token, you can use it to make authenticated requests to the server. If you include the correct `access_token` parameter in your query, you'll be logged in as that user for that request.
|
73
73
|
|
74
|
-
Try it out for yourself
|
74
|
+
Try it out for yourself. Replace the access token below with the one you received and run this curl command:
|
75
75
|
|
76
|
-
$ curl "<%=
|
76
|
+
$ curl "<%= oauth_test_url(:show_me_the_money, :access_token => '9693accessTokena7ca570bbaf') %>"
|
77
77
|
|
78
78
|
|
79
79
|
|
80
|
-
You should see a successful result (
|
80
|
+
You should see a successful result (again, don't forget to replace the example access token with yours). Note that all urls will support OAuth authentication.
|
81
81
|
|
82
|
-
You can also use a header to pass the
|
82
|
+
You can also use a header to pass the OAuth token:
|
83
83
|
|
84
|
-
$ curl -H "Authorization: token 9693accessTokena7ca570bbaf" "<%=
|
84
|
+
$ curl -H "Authorization: token 9693accessTokena7ca570bbaf" "<%= oauth_test_url(:show_me_the_money) %>"
|
85
85
|
|
86
86
|
|
87
87
|
## Security
|