GithubHelp home page GithubHelp logo

baskin / hasura-backend-plus Goto Github PK

View Code? Open in Web Editor NEW

This project forked from nhost/hasura-backend-plus

0.0 1.0 0.0 934 KB

🔑Auth and 📦Storage for Hasura. The quickest way to get Auth and Storage working for your next app based on Hasura.

Home Page: https://nhost.io

License: MIT License

JavaScript 91.05% Dockerfile 0.33% PLpgSQL 8.63%

hasura-backend-plus's Introduction

HBP

Hasura Backend Plus (HBP)

Auth & Files (S3-compatible Object Storage) for Hasura


Nhost

The easiest way to deploy HBP is with our official Nhost managed service. Get your perfect configured backend with PostgreSQL, Hasura and Hasura Backend Plus and save yourself hours of maintenance per month.

All Nhost projects are built on open source software so you can make realtime web and mobile apps fast 🚀.

https://nhost.io


Setup

Get your database ready

Create the tables and initial state for your user management by copying everything from the file db-init.sql, and insert into the SQL tab in the Hasura Console.

Track your tables and relations in Hasura

Go to the Hasura console. Click the "Data" menu link and then click "Track all" under both "Untracked tables or views" and "Untracked foreign-key relations"

Create minimal storage rules

In the same directory where you have your docker-compose.yaml for your Hasura and HBP project. Do the following:

mkdir storage-rules
vim storage-rules/index.js

Add this:

module.exports = {

  // key - file path
  // type - [ read, write ]
  // claims - claims in JWT
  // this is similar to Firebase Storage Security Rules.

  storagePermission: function(key, type, claims) {
    // UNSECURE! Allow read/write all files. Good to get started though
    return true;
  },
};

Deploy

Add to docker-compose.yaml:

hasura-backend-plus:
  image: nhost/hasura-backend-plus:latest
  environment:
    PORT: 3010
    AUTH_ACTIVE: 'true'
    AUTH_LOCAL_ACTIVE: 'true'
    USER_FIELDS: ''
    USER_REGISTRATION_AUTO_ACTIVE: 'true'
    HASURA_GRAPHQL_ENDPOINT: http://graphql-engine:8080/v1/graphql
    HASURA_GRAPHQL_ADMIN_SECRET: <hasura-admin-secret>
    HASURA_GRAPHQL_JWT_SECRET: '{"type": "HS256", "key": "a_pretty_long_secret_key"}'
    S3_ACCESS_KEY_ID: <access>
    S3_SECRET_ACCESS_KEY: <secret>
    S3_ENDPOINT: <endpoint>
    S3_BUCKET: <bucket>
    REFRESH_TOKEN_EXPIRES: 43200
    JWT_TOKEN_EXPIRES: 15
  volumes:
  - ./storage-rules:/app/src/storage/rules

caddy:
  ....
  depends_on:
  - graphql-engine
  - hasura-backend-plus

Add this to your caddy file

hasura.myapp.io {
  proxy / graphql-engine:8080 {
    websocket
    transparent
  }
}

backend.myapp.io {
  proxy / hasura-backend-plus:3010 {
    transparent
  }
}

Restart your docker containers

docker-compose up -d

Configuration

ENV VARIABLES:

Name Default Description
PORT 3010 Express server port
AUTH_ACTIVE true Activate authentication
USER_FIELDS `` Specify user table fields that should be available as x-hasura- JWT claims.
USER_REGISTRATION_AUTO_ACTIVE false Whether new user account should automatically be activated. Accounts that are not active are unable to log in
JWT_TOKEN_EXPIRES 15 Minutes until JWT token expires
REFRESH_TOKEN_EXPIRES 43200 (30 days) Minutes until refresh token expires
AUTH_LOCAL_ACTIVE false Activate authentication for local accounts
AUTH_ANONYMOUS_USERS_ACTIVE false Allow anonymous users
PROVIDERS_SUCCESS_REDIRECT `` The URL the user should be redirected to on successful signin/signup with a OAuth provider.
PROVIDERS_FAILURE_REDIRECT `` The URL the user should be redirected to on failed signin/signup with a OAuth provider.
AUTH_GITHUB_ACTIVE false Activate Github as an OAuth provider
AUTH_GITHUB_CLIENT_ID `` Github OAuth app Client ID
AUTH_GITHUB_CLIENT_SECRET `` Github OAuth app Client Secret
AUTH_GITHUB_CALLBACK_URL `` Github OAuth app authorization callback URL
AUTH_GITHUB_AUTHORIZATION_URL `` Github (enterprise) OAuth app authorization url
AUTH_GITHUB_TOKEN_URL `` Github (enterprise) OAuth app token url
AUTH_GITHUB_USER_PROFILE_URL `` Github (enterprise) OAuth app user profile url
AUTH_GOOGLE_ACTIVE false Activate Google as an OAuth provider
AUTH_GOOGLE_CLIENT_ID `` Google OAuth app Client ID
AUTH_GOOGLE_CLIENT_SECRET `` Google OAuth app Client Secret
AUTH_GOOGLE_CALLBACK_URL `` Google OAuth app authorization callback URL
AUTH_FACEBOOK_ACTIVE false Activate Facebook as an OAuth provider
AUTH_FACEBOOK_CLIENT_ID `` Facebook OAuth app Client ID
AUTH_FACEBOOK_CLIENT_SECRET `` Facebook OAuth app Client Secret
AUTH_FACEBOOK_CALLBACK_URL `` Facebook OAuth app authorization callback URL
STORAGE_ACTIVE true Activate storage
HASURA_GRAPHQL_ENDPOINT http://graphql-engine:8080/v1/graphql Hasura GraphQL endpoint
HASURA_GRAPHQL_ADMIN_SECRET `` Hasura GraphQL admin secret
HASURA_GRAPHQL_JWT_SECRET { 'type': 'HS256', 'key': 'secretkey' } Shared JWT secret. Must be same as Hasura's HASURA_GRAPHQL_JWT_SECRET
S3_ACCESS_KEY_ID `` S3 access key id
S3_SECRET_ACCESS_KEY `` S3 secret access key
S3_ENDPOINT `` S3 endpoint
S3_BUCKET `` S3 bucket name

USER_FIELDS

If you have some specific fields on your users that you also want to have as a JWT claim you can specify those user fields in the USER_FIELDS env var.

So let's say you have a user table with the following columns:

  • id
  • email
  • password
  • role
  • company_id

And you want to include the company_id as a JWT claim. You can specify USER_FIELDS=company_id.

Then you will have a JWT a little something like this:

{
  "https://hasura.io/jwt/claims": {
    "x-hasura-allowed-roles": [
      "user"
      "company_admin"
    ],
    "x-hasura-default-role": "company_admin",
    "x-hasura-user-id": "3",
    "x-hasura-company-id": "1" <------ THERE WE GO :)
  },
  "iat": 1549526843,
  "exp": 1549527743
}

This enables you to make permissions using x-hasura-company-id for insert/select/update/delete in on tables in your Hasura console. Like this: {"seller_company_id":{"_eq":"X-Hasura-Company-Id"}}

It also enables you to write permission rules for the storage endpoint in this repo. Here is an example: https://github.com/nhost/hasura-backend-plus/blob/master/src/storage/rules/index.js

HASURA_GRAPHQL_ENDPOINT

Auth

/auth/refresh-token
/auth/activate-account
/auth/users

Refresh Token

/auth/refresh-token

POST

Returns a JWT token.

Activate Account

/auth/local/activate-account

POST

Variable Type Required
secret_token uuid YES

User

/auth/user

Returns the full User object

Auth Local

/auth/local/register
/auth/local/login
/auth/local/new-password

Use HTTP POST method.

Register

/auth/local/register

POST

Variable Type Required Comment
email string NO
username string YES can be same as email
password string YES
register_data json object NO

Login

/auth/local/login

POST

Variable Type Required
username string YES
password string YES

New password

/auth/local/new-password

POST

Variable Type Required
secret_token uuid YES
password text YES

Register your first user

curl -X POST \
  http://localhost:3010/auth/local/register \
  -H 'Content-Type: application/json' \
  -H 'cache-control: no-cache' \
  -d '{
	"username": "testuser",
	"password": "test"
}'

The response is: OK!

Login using that user

curl -X POST \
  http://localhost:3010/auth/local/login \
  -H 'Content-Type: application/json' \
  -H 'cache-control: no-cache' \
  -d '{
    "username": "testuser",
    "password": "test"
}'

This will have a valid token in the response:

{
    "jwt_token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJodHRwczovL2hhc3VyYS5pby9qd3QvY2xhaW1zIjp7IngtaGFzdXJhLWFsbG93ZWQtcm9sZXMiOlsidXNlciJdLCJ4LWhhc3VyYS1kZWZhdWx0LXJvbGUiOiJ1c2VyIiwieC1oYXN1cmEtdXNlci1pZCI6IjEifSwiaWF0IjoxNTYxMzY0NTY1LCJleHAiOjE1NjEzNjU0NjV9.j4Jvf_hzxStrs80PQyda9RwM3XClCymHHX_uE-y7Nhc",
    "refresh_token": "b760234c-f36b-47ff-8044-b32e40ee1ad2",
    "user_id": 1
}

OAuth providers

/auth/github
/auth/google

Storage

Will act as a proxy between your client and a S3 compatible block storage service (for example: AWS S3, Digital Ocean Spaces, Minio). HBP can handle read, write and security permissions. Digital Ocean offers S3-compatible object storage for $5/month, with 250 GB of storage and 1TB outbound transfer. https://www.digitalocean.com/products/spaces/. You can also use open source self-hosted private cloud storage solutions like Minio.

Uploads

Upload a file blob to /storage/upload. Will return key, originalname and mimetype. You can upload one file at a time.

Download (get)

GET storage/file/{key}

Delete (get)

DELETE /storage/file/{key}

Get download token

GET /storage/fn/get-download-url/{key}.

Returns:

{
  "token": "cce1193c-a299-400b-9e70-2b33b11fd113",
}

Use this token with /storage/file/{file}?token={token}.

This token will give permanent access to the file.

Security

Security rules are placed in storage-tools.js in the function validateInteraction.

key = Interacted file. Ex: /companies/2/customer/3/report.pdf.

type = Operation type. Can be one of: read, write.

claims = JWT claims coming https://hasura.io/jwt/claims custom claims in the Hasura JWT token. Ex: claims['X-Hasura-User-Id'].

Example:

File: src/storage/storage-rules.js

Code:

module.exports = {

  // key - file path
  // type - [ read, write ]
  // claims - claims in JWT
  // this is similar to Firebase Security Rules for files. but not as good looking
  storagePermission: function(key, type, claims) {
    let res;

    // console.log({key});
    // console.log({type});
    // console.log({claims});

    res = key.match(/\/companies\/(?<company_id>\w*)\/customers\/(\d*)\/.*/);
    if (res) {
      if (claims['x-hasura-company-id'] === res.groups.company_id) {
        return true;
      }
      return false;
    }

    // accept read to public directory
    res = key.match(/\/public\/.*/);
    if (res) {
      if (type === 'read') {
        return true;
      }
    }

    return false;
  },
};

You can see other examples here in examples folder.

nhost-js-sdk

Use nhost-js-sdk for client side interaction with Hasura Backend Plus.

hasura-backend-plus's People

Contributors

aaronhayes avatar babakscript avatar batuaksoy avatar elitan avatar frissonlabs avatar joaovpmamede avatar maartennnn avatar marcellothearcane avatar mnlbox avatar nkabbara avatar rodolfosilva avatar tobiastornros avatar

Watchers

 avatar

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.