Skip to content

Simple Example of a Rails API Auth Service utilizing OAuth2, OpenID Connect, JWTs and more.

Notifications You must be signed in to change notification settings

dsabira/rails-api-auth-service

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

1 Commit
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Simple Rails API Auth Service Example

Utilizes:

  • OAUth2
  • OpenID Connect
  • JWT / Identity Token
  • Opaque Access Token
  • Rails API
  • PostgreSQL

This is a very basic example. Many additional improvements should be made for a Production ready product.
Assumes Front End operates on localhost:3000 (CORS)
Assumes this auth service operates on localhost:4000
Requires a private key in the initializer for doorkeeper\openid_connect
ssh-keygen -t rsa -b 4096 -f i ~/.ssh/TEST-AUTH -N '' sed 's/$/\\n/' ~/.ssh/TEST-AUTH | tr -d '\n' and add to initializer (not directly, do not commit to repo, consider Figaro / dotenv, etc.)

To Use for Development

  1. Generate Private Key as outlined above and add to doorkeeper_openid_connect initializer.
  2. Run the auth service on localhost:4000
  3. Access via a client on localhost:3000 (or Postman, etc)

Steps Taken to Create This Service

  1. bundle install devise, doorkeeper, doorkeeper-openid_connect, rack-cors gems
  2. rails db:create
  3. Configure config/initializers/cors as needed (least privilege necessary)
  4. Install Devise
rails g devise:install  
rails g devise user
rails db:migrate  
  1. Install Doorkeeper
    rails g doorkeeper:install
    Configure Doorkeeper Initializer
    rails g doorkeeper:migration && rails db:migrate
  2. Add migration designating User as the resource_owner && rails db:migrate
  3. Configure api controller for authorization & json
  4. Remove doorkeeper authorization from controllers as appropriate with skip\_before\_action
  5. rails g devise:controllers [users]
  6. Config barebone Devise route
  7. Add strong params to registrations controller
  8. Seed database for dummy front end client (NOTE: usually handled via config variables but skipped for simplicity)
    rails db:seed
  9. From rails console, obtain client_id for OAuth requests Doorkeeper::Application.last.uid (remember: simple example, not production)
  10. Config barebone Doorkeeper routes
  11. Install Doorkeeper Open ID Connect
rails generate doorkeeper:openid\_connect:install  
rails generate doorkeeper:openid\_connect:migration  
rails db:migrate  
  1. Update doorkeeper_openid_connect initializer
  2. Start your basic sample auth service on localhost:4000
  3. Submit requests from client (see documentation below)
  4. Decode JWT (client, other service, etc) with the Public Key

API Documentation

Authentication via Devise

  • Registration POST /users email, password, password_confirmation (validate client side)
{
  "user": {
    "email": "josh@gmail.com",
    "password": "newpass",
    "password_confirmation": "newpass"
  }
}
Return user resource 
{
  "id": 1,
  "email": "josh@gmail.com",
  "created_at": "2017-01-06T15:15:46.912Z",
  "updated_at": "2017-01-06T15:15:46.916Z"
}

Delegation via Doorkeeper

  • Access Token POST /oauth/token grant_type, email, password, client_id
{
  "grant_type": "password",
  "email": "josh@gmail.com",
  "password": "newpass",
  "scope": "openid",
  "client_id": "506b281cbd25d7d8b573db77dce4-generated-client-id"
}

Returns tokens

{
  "access_token": "800302477be2b381fbb7b90bf4a92d945a809ca3dc0771c690556ef35d6572b7",
  "token_type": "bearer",
  "expires_in": 86400,
  "scope": "openid",
  "created_at": 1483718426,
  "id_token": "eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiIsImtpZCI6IlFXTThGa05KYlBWVjNHaFdTN2ZtSmpTSmNOZ0VHREZZQkxWeGtIU0lnU0EifQ.eyJpc3MiOiJodHRwOi8vbG9jYWxob3N0OjQwMDAiLCJzdWIiOiIxIiwiYXVkIjoiNTA2YjI4MWNiZDI1ZDdkOGI1NzNkYjc3ZGNlNDZjODg0ZWQ1OGU5MGZkMzdhYTNhODJhYmVjODVhZGYwNjRjYSIsImV4cCI6MTQ4MzcxODU0NiwiaWF0IjoxNDgzNzE4NDI2LCJhdXRoX3RpbWUiOjE0ODM3MTg0MjZ9.eYebizB1IoimCzEdTnizdSnl0Qvnpmw8_1zcfJuYqdTzI0ox_t_OUQi8lu06Gts03ybWfIdfdGy6La3oR1E8XiQLcRCU2t_CagC2203DJJoxhK3vi5HP7fSlYvGWLXXNLZLXLNgLCkQvsWaatqaOJSlNoD6nelHnQNQ6aUT2vDLhOHXtoXY7Q78g68EG64RLItiRgGipgBGsjcNRV0w9Zscrd40GuMxnbjgLEl6iEU0RTyG10p154ilepjP3nVHYmx5kx_qPSzF8_58kBActH2ECojaLX83ROZ4frTDS4zbIlVEh_RxW_AgVGE5o8HyW559jaOT3a4YnercYESqMFkjW1Or_BCKI_BWkI69ePwXfkvsRFif5XO2vIg2BOcpxoVOt3MEGVunvG8BFYU0SEalChB4i4vuniAFxIZ2VrQWK3cBAcwVtP7RxrYH1ukzqsQcsHsVoFQH0ijAdtgIFmg43xtP_96qUQ0fOVlDTzUph4EWmHLmT3oevcjN07j0WMgt7skZta-L49nV4W3Ykij3IFB7E1rNGxJO0lT1nmFlz9ni099-tuIpaPSasiIGfvqbz-50WQ5nzWQCnnEWvcqm_Vi8aWbLVnDUDwtcYcXWGQ7UdV6rfTkjJHDXLe1lwPVpye71rjB87DwfH4_15F_nm00RuoDWzCVpABiePThY"
}
  • Access Token Info
    GET /oauth/token/info Authorization: Bearer AT
    Must pass Access Token as an Authorization Header
    Returns Access Token Info
{
  "resource_owner_id": 1,
  "scopes": [
    "openid"
  ],
  "expires_in_seconds": 86302,
  "application": {
    "uid": "506b281cbd25d7d8b573db77dce46c884ed58e90fd37aa3a82abec85adf064ca"
  },
  "created_at": 1483719570
}
  • Revoke Access Token
    POST /oauth/revoke token
    Returns 200

Identity via Doorkeeper OpenID Connect

  • Get Identity Info
    GET /oauth/userinfo Authorization: Bearer AT
    Must pass Access Token as an Authorization Header
    Authorization: Bearer 800302477be2b381fbb7b90bf4a92d945a809ca3dc0771c690556ef35d6572b7
    Returns sub & additional claims if created / specified (not included here but see below)
{
  "sub": "1"
}

Additional Features to Consider

Add more claims such as profile Configure Devise Model: add name to model, migration, controller (strong parameters) and doorkeeper_openid_connect so it can be returned with Identity
Configure Devise Model: remove options (rememberable, for example) & update with a migration
Add more routes as appropriate (Devise has many built in)
uuid:
Enable uuid as primary key uuid in Rails 5
uuid in Doorkeeper / Postgres
json-api: How and Why to Use JSON API w/ Rails Figaro: Use Figaro env variables for database secrets CORS: Lock down CORS in initializer Add custom mailer - extend application_mailer, create custom mailer, add custom mailer layouts, add to devise initializer
Consider moving mailer to separate service
Install SES API gem for mailing, if appropriate

About

Simple Example of a Rails API Auth Service utilizing OAuth2, OpenID Connect, JWTs and more.

Resources

Stars

Watchers

Forks

Packages

No packages published