Tweaks the text, adds a design remark about SQL functions and adds the token TTL in HTTP cache headers
This commit is contained in:
@@ -21,7 +21,7 @@ so I'm assuming that the reader's authentication system is already working.
|
||||
|
||||
### Sharing the JWT Secret
|
||||
|
||||
To allow a third party to generate valid JWTs for your PostgREST API
|
||||
Allowing a third party to generate valid JWTs for your PostgREST API
|
||||
is just a matter of sharing a secret. So you need to give your authenticator
|
||||
software the same secret that was used in your API server under the ```--jwt-secret```
|
||||
parameter.
|
||||
@@ -42,11 +42,11 @@ I'll add a text field called role to my users table:
|
||||
ALTER TABLE users ADD role text NOT NULL DEFAULT 'customer';
|
||||
```
|
||||
|
||||
For our example we will need besides the main user that PostgREST uses to connect to PostgreSQL
|
||||
and the anonymous user, we will have two aditional roles:
|
||||
Besides the main user that PostgREST uses to connect to PostgreSQL
|
||||
and the anonymous user, we will need two aditional roles for our example:
|
||||
|
||||
* admin - to be used by users where admin = true
|
||||
* customer - to be used where admin = false
|
||||
* admin - to be used by users that access all the system rows.
|
||||
* customer - to be used when user has restricted access to database rows.
|
||||
|
||||
Bellow we have the commands to create all roles that will be used:
|
||||
```sql
|
||||
@@ -55,7 +55,7 @@ CREATE ROLE anonymous;
|
||||
CREATE ROLE admin;
|
||||
CREATE ROLE customer;
|
||||
|
||||
GRANT customer, admin, anonymous TO postgrest;
|
||||
GRANT customer, admin, anonymous TO authenticator;
|
||||
```
|
||||
|
||||
### Generating a JWT
|
||||
@@ -75,6 +75,8 @@ For this I just open a file ```app/controllers/api_tokens_controller.rb``` with
|
||||
|
||||
```ruby
|
||||
class ApiTokensController < ApplicationController
|
||||
TOKEN_TTL = 1.hour
|
||||
|
||||
def show
|
||||
unless ENV['JWT_SECRET'].present?
|
||||
return render json: {error: "you need to have JWT_SECRET configured to get an API token"}, status: 500
|
||||
@@ -84,6 +86,7 @@ class ApiTokensController < ApplicationController
|
||||
return render json: {error: "only authenticated users can request the API token"}, status: 401
|
||||
end
|
||||
|
||||
expires_in TOKEN_TTL, public: false
|
||||
render json: {token: jwt}, status: 200
|
||||
end
|
||||
|
||||
@@ -93,10 +96,12 @@ class ApiTokensController < ApplicationController
|
||||
end
|
||||
|
||||
def claims
|
||||
# I'm assuming a boolean field admin in the user model indicating wheter the
|
||||
# user has administrative privileges.
|
||||
# This token will expire 1 hour after being issued
|
||||
{ role: current_user.role, user_id: current_user.id.to_s, exp: (Time.now + 1.hour).to_i }
|
||||
{
|
||||
role: current_user.role,
|
||||
user_id: current_user.id.to_s,
|
||||
exp: (Time.now + TOKEN_TTL).to_i
|
||||
}
|
||||
end
|
||||
end
|
||||
```
|
||||
@@ -113,8 +118,9 @@ whose value is the token the API requests should use.
|
||||
|
||||
### Orders Endpoint
|
||||
|
||||
Here we describe how to create a view to generate an endpoint /orders filtered by
|
||||
the logged in user.
|
||||
Here is how to create a view to generate an endpoint ```/orders``` filtered by
|
||||
the logged in user:
|
||||
|
||||
```sql
|
||||
ALTER DATABASE mydb SET postgrest.claims.user_id TO '';
|
||||
|
||||
@@ -144,10 +150,20 @@ WHERE
|
||||
current_user = 'admin' OR o.user_id = current_user_id();
|
||||
```
|
||||
|
||||
<div class="admonition note">
|
||||
<p class="admonition-title">DRY priviledge checking conditions</p>
|
||||
<p>
|
||||
You can encapsulate conditions that will be commonly used to check for privileges while reading a database row.
|
||||
We used a function <code>current_user_id()</code> but we could add more conditions to functions
|
||||
as the system becomes more complex.<br/>
|
||||
Remeber to mark your functions as <code>STABLE</code> so that PostgreSQL can inline then while planning the query.
|
||||
</p>
|
||||
</div>
|
||||
|
||||
### Using the JWT
|
||||
|
||||
Now any page generated by our Rails app, after we are authenticated we can use a simple
|
||||
Javascript code to get our token and use it:
|
||||
Now whenever you are authenticated in your Rails application you can use some Javascript
|
||||
code to get the token and use it:
|
||||
```javascript
|
||||
$.getJSON('/api_json').done(function(data){
|
||||
$.ajax('/orders', {'Authorization': 'Bearer ' + data.token})
|
||||
|
||||
Reference in New Issue
Block a user