@sgrove/onegraph-apollo-server-auth
v2.0.3-alpha-2
Published
Auth helpers for apollo server using OneGraph AuthGuardian
Downloads
9
Readme
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 ofuser.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 ofuser.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
- First, install the auth package:
npm install --save onegraph-apollo-server-auth
# or
yarn add onegraph-apollo-server-auth
- 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 id
s, 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!