@sgrove/onegraph-apollo-server-auth

2.0.3-alpha-2 • Public • Published

OneGraph Auth for Apollo Server

You can use AuthGuardian by OneGraph to handle all of your authentication and permission needs in your Apollo server.

Just give me an example project to try!

Good point! We have a basic example apollo-server app with OneGraph AuthGuardian you can clone and try out! Just clone the repo, follow the instructions, and you'll have a fully secured GraphQL API!

At a glance

AuthGuardian is the easiest way to allow someone to access your API based on information in GitHub, Salesforce, Gmail, etc. It lets you graphically configure sophisticated rules that will run every time a user logs in to any service (GitHub, Salesforce, Quickbooks, etc.) via OneGraph and will produce a JWT that contains everything you need to know who a user is and what they're allowed to do in your API.

Each rule consists of two parts: conditions and effects.

An example of a rule condition might be,

"When this user is a member of organization X on GitHub AND this user has made at least one commit to the repository repo-owner/repo-name".

OneGraph knows how to query each of the services to find out if the condition has been met automatically!

When all of the conditions for a rule are met, the effects are run. An effect might be:

Set the user.id to the user's GitHub user-id, and add "admin" to the list of user.roles

So the full rule would read:

"When this user is a member of organization X on GitHub AND this user has made at least one commit to the repository repo-owner/repo-name". Then set the user.id to the user's GitHub user-id AND add "admin" to the list of user.roles AND add a Netlify role of "developer"

If this rule passed after a user logged in via GitHub, OneGraph would generate a full, signed JWT for use in your GraphQL resolvers:

{
  "iss": "OneGraph",
  "aud": "https://serve.onegraph.com/dashboard/app/00000000-0000-0000-0000-000000000000",
  "iat": 1566594200,
  "exp": 1566680600,
  "user": {
    "id": 35296,
    "roles": [
      "admin"
    ]
  },
  "app_metadata": {
    "authorization": {
      "roles": [
        "developer"
      ]
    }
  }
}

Using the OneGraph JWT in Apollo Server

  1. First, install the auth package:
npm install --save onegraph-apollo-server-auth
# or 
yarn add onegraph-apollo-server-auth
  1. Use the custom directives There are two customer directives implemented by onegraph-apollo-server-auth, @isAuthencated and @hasRoles:
directive @isAuthenticated on QUERY | FIELD_DEFINITION
directive @hasRole(oneOf: [String!]) on QUERY | FIELD_DEFINITION

@isAuthenticated

Any field that has this directive added to is will always check in the JWT that a value is present at user.id. If not, the user has not authenticated (that is, has not logged into any service), and the field will return null, and an error message will be added to the response.

type Query {
  companies : [Company] @isAuthenticated
}

@hasRole

Any field with this directive added will check in the JWT at the path user.roles to make sure that the user has been granted a role that's required to view this field.

type Company {
  id: String!
  name: String @hasRole(oneOf: ["visitor"])
  accountBalance: Int! @hasRole(oneOf: ["admin"])
}

In this case, any user will be able to query for Company ids, but the AuthGuardian rules must have granted this user the visitor role to view the Company name, and the admin role to view the Company accountBalance.

Put it all together!

const { ApolloServer } = require("apollo-server-express");
const { schema } = require("./schema.js");
const {
  extractBearerToken,
  hasRoleDirective,
  isAuthenticatedDirective,
  makeOneGraphJwtVerifier
} = require("onegraph-apollo-server-auth");

const verifyJwt = makeOneGraphJwtVerifier(appId);

const server = new ApolloServer({
  typeDefs: schema,
  resolvers,
  schemaDirectives: {
    hasRole: hasRoleDirective,
    isAuthenticated: isAuthenticatedDirective
  },
  context: async incoming => {
    const token = extractBearerToken(incoming.req);

    if (!token) {
      return { jwt: null };
    }

    try {
      const decoded = await verifyJwt(token).catch(rejection =>
        console.warn(`JWT verification failed: `, rejection)
      );
      return { jwt: decoded };
    } catch (rejection) {
      console.warn(rejection);
      return { jwt: null };
    }
  }
});

And that's it! With just a few bits of annotation to your schema and a few minutes to configure the AuthGuardian rules, your entire authentication and permissions system can be taken care of securely!

Logging in your users via the OneGraph Auth Client

See the instructions on how to quickly get your users logging in via Onegraph Auth. Here's a rough summary:

Install the onegraph-auth package on your client:

npm install --save onegraph-auth
# or
yarn add onegraph-auth

Instantiate the auth client in the browser (with the same APP_ID you used to configure AuthGuardian):

import OneGraphAuth from 'onegraph-auth';

const APP_ID = YOUR_APP_ID;

const auth = new OneGraphAuth({
  appId: APP_ID,
});

And log in your user (in this case via github):

auth
  .login('github')
  .then(() => {
    auth.isLoggedIn('github').then(isLoggedIn => {
      if (isLoggedIn) {
        console.log('Successfully logged in to GitHub');
      } else {
        console.log('Did not grant auth for GitHub');
      }
    });
  })
  .catch(e => console.error('Problem logging in', e));

That's it! At the end of that flow, all of your AuthGuardian rules will have run, and the user will have a JWT that reflects their authentication and permissions for your API!

Readme

Keywords

none

Package Sidebar

Install

npm i @sgrove/onegraph-apollo-server-auth

Weekly Downloads

0

Version

2.0.3-alpha-2

License

MIT

Unpacked Size

52 kB

Total Files

11

Last publish

Collaborators

  • sgrove