Skip to content
This repository has been archived by the owner on May 26, 2022. It is now read-only.

Remove the need to verify the token per request #17

Merged
merged 4 commits into from
Feb 24, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
23 changes: 21 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -86,10 +86,15 @@ const client = new ApolloClient({
Configuration is done via environment variables.

(required)
You must set the `JWT_SECRET` environment variable:
There are two variables to control how tokens are processed.
If you would like the server to verify the tokens used in a request, you must provide the secret used to encode the token in the `JWT_SECRET` variable. Otherwise you will need to set `JWT_NO_VERIFY` to true.

```sh
export JWT_SECRET=><YOUR_JWT_SECRET_KEY_HERE>
export JWT_NO_VERIFY=true //Server does not have the secret, but will need to decode tokens
```
or
```sh
export JWT_SECRET=><YOUR_JWT_SECRET_KEY_HERE> //Server has the secret and will verify autheniticty
```

(optional)
Expand All @@ -107,6 +112,20 @@ Set:
export AUTH_DIRECTIVES_ROLE_KEY=https://grandstack.io/roles
```

## Running Tests Locally

1. create ./test/helpers/.env
2. add relevant values
3. run the test server
```sh
npx babel-node test/helpers/test-setup.js
```
4. run the tests
```sh
npx ava test/*.js
```


## Test JWTs

Scopes: user:CRUD
Expand Down
19 changes: 8 additions & 11 deletions src/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -23,18 +23,15 @@ const verifyAndDecodeToken = ({ context }) => {
const token = req.headers.authorization || req.headers.Authorization;
try {
const id_token = token.replace("Bearer ", "");
const JWT_SECRET = process.env.JWT_SECRET;
const {JWT_SECRET, JWT_NO_VERIFY} = process.env;

if (!JWT_SECRET) {
throw new Error(
"No JWT secret set. Set environment variable JWT_SECRET to decode token."
);
if (!JWT_SECRET && JWT_NO_VERIFY) {
return jwt.decode(id_token)
} else {
return jwt.verify(id_token, JWT_SECRET, {
algorithms: ["HS256", "RS256"]
});
}
const decoded = jwt.verify(id_token, JWT_SECRET, {
algorithms: ["HS256", "RS256"]
});

return decoded;
} catch (err) {
throw new AuthorizationError({
message: "You are not authorized for this resource"
Expand Down Expand Up @@ -85,7 +82,7 @@ export class HasScopeDirective extends SchemaDirectiveVisitor {

visitObject(obj) {
const fields = obj.getFields();
const expectedScopes = this.args.roles;
const expectedScopes = this.args.scopes;

Object.keys(fields).forEach(fieldName => {
const field = fields[fieldName];
Expand Down
5 changes: 3 additions & 2 deletions test/test.js
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ test("No error with token", async t => {

const headers = {
Authorization:
"Bearer eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpc3MiOiJHUkFORHN0YWNrIiwiaWF0IjoxNTQ5MTQ1Mjk0LCJleHAiOjE1ODA2ODEzMDcsImF1ZCI6ImdyYW5kc3RhY2suaW8iLCJzdWIiOiJib2JAbG9ibGF3LmNvbSIsIlJvbGUiOiJBRE1JTiIsIlNjb3BlIjpbIlVzZXI6UmVhZCIsIlVzZXI6Q3JlYXRlIiwiVXNlcjpVcGRhdGUiLCJVc2VyOkRlbGV0ZSJdfQ.nKADki8iKTpKqq3CVdrGAUrSzSBmFolWzYOsA_ULSdo"
"Bearer eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpc3MiOiJHUkFORHN0YWNrIiwiaWF0IjoxNTQ5MTQ1Mjk0LCJleHAiOjE2OTE3ODEzMDcsImF1ZCI6ImdyYW5kc3RhY2suaW8iLCJzdWIiOiJib2JAbG9ibGF3LmNvbSIsIlJvbGUiOiJBRE1JTiIsIlNjb3BlIjpbIlVzZXI6UmVhZCIsIlVzZXI6Q3JlYXRlIiwiVXNlcjpVcGRhdGUiLCJVc2VyOkRlbGV0ZSJdfQ.WJffOec05r8KuzW76asax1iCzv5q4rwRv9kvFyw7c_E"
};

const client = new ApolloClient({
Expand All @@ -76,6 +76,7 @@ test("No error with token", async t => {
t.pass();
})
.catch(error => {
console.error(error)
t.fail();
});
});
Expand All @@ -86,7 +87,7 @@ test("Mutation resolver is not called when Auth fails", async t => {
// This JWT does not contain User:Create scope claim
const headers = {
Authorization:
"Bearer eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpc3MiOiJHUkFORHN0YWNrIiwiaWF0IjoxNTQ5MTQ1Mjk0LCJleHAiOjE1ODA2ODEzMDcsImF1ZCI6ImdyYW5kc3RhY2suaW8iLCJzdWIiOiJib2JAbG9ibGF3LmNvbSIsIlJvbGUiOiJBRE1JTiIsIlNjb3BlIjpbIlVzZXI6UmVhZCIsIlVzZXI6VXBkYXRlIiwiVXNlcjpEZWxldGUiXX0.cXOlwyZOi--tHmLyf32iC37JXGj4DrvdOsQVK5VHmuY"
"Bearer eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpc3MiOiJHUkFORHN0YWNrIiwiaWF0IjoxNTQ5MTQ1Mjk0LCJleHAiOjE2OTE3ODEzMDcsImF1ZCI6ImdyYW5kc3RhY2suaW8iLCJzdWIiOiJib2JAbG9ibGF3LmNvbSIsIlJvbGUiOiJBRE1JTiIsIlNjb3BlIjpbIlVzZXI6UmVhZCIsIlVzZXI6VXBkYXRlIiwiVXNlcjpEZWxldGUiXX0.J3VrFNSKToK1cZNrwdbKp-8YkO74_tkp82l3n39ZnK0"
};

const client = new ApolloClient({
Expand Down