-
Notifications
You must be signed in to change notification settings - Fork 1.1k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
9 changed files
with
692 additions
and
1 deletion.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
--- | ||
'@keystone-next/example-next-auth': major | ||
--- | ||
|
||
Initial version of the `withAuth` example. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
# @keystone-next/example-with-auth |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,82 @@ | ||
## Feature Example - Authentication | ||
|
||
This project demonstrates how to add password based authentication to your Keystone system. | ||
It builds on the [Task Manager](../todo) starter project. | ||
|
||
## Instructions | ||
|
||
To run this project, clone the Keystone repository locally then navigate to this directory and run: | ||
|
||
```shell | ||
yarn dev | ||
``` | ||
|
||
This will start the Admin UI at [localhost:3000](http://localhost:3000). | ||
You can use the Admin UI to create items in your database. | ||
|
||
You can also access a GraphQL Playground at [localhost:3000/api/graphql](http://localhost:3000/api/graphql), which allows you to directly run GraphQL queries and mutations. | ||
|
||
## Features | ||
|
||
This project demonstrates how to add authentication to a Keystone system. | ||
We're going to use the [`@keystone-next/auth`](https://next.keystonejs.com/apis/auth) package, along with Keystone's [session management API](https://next.keystonejs.com/apis/session), to add the following features to the base system: | ||
|
||
* Configure which fields to use for signin | ||
* Set up stateless session handling to keep track of the signed in user | ||
* Add a signin screen to the Admin UI | ||
* Add a signout button to the Admin UI | ||
* Allow the signed in user to access their own details in the Admin UI | ||
* Add a helper page to the Admin UI to allow you to create your first user when starting from an empty database | ||
|
||
### Added fields | ||
|
||
In this example we add two new fields, `email` and `password`, to the `Person` list. | ||
These are used as our _identity_ and _secret_ fields for login. | ||
|
||
```typescript | ||
email: text({ isRequired: true, isUnique: true }), | ||
password: password({ isRequired: true }), | ||
``` | ||
|
||
### Auth config | ||
|
||
We use the `createAuth` function from `@keystone-next/auth` to configure a `withAuth` config wrapper, which will inject all the extra config used to enabled configuration. | ||
|
||
```typescript | ||
import { createAuth } from '@keystone-next/auth'; | ||
|
||
const { withAuth } = createAuth({ | ||
listKey: 'Person', | ||
identityField: 'email', | ||
secretField: 'password', | ||
initFirstItem: { fields: ['name', 'email', 'password'] }, | ||
}); | ||
``` | ||
|
||
### Session | ||
|
||
We use a basic `statelessSessions` from `@keystone-next/keystone/session` for session handling. | ||
You need to have sessions enabled in order to use the `withAuth` config wrapper. | ||
|
||
```typescript | ||
import { statelessSessions } from '@keystone-next/keystone/session'; | ||
|
||
const session = statelessSessions({ secret: '-- EXAMPLE COOKIE SECRET; CHANGE ME --' }); | ||
``` | ||
|
||
### Wrapped config | ||
|
||
We wrap our config using the `withAuth` function, which injects added Admin UI configuration, as well as the GraphQL queries and mutations for authentication. | ||
|
||
```typescript | ||
export default withAuth( | ||
config({ | ||
db: { | ||
provider: 'sqlite', | ||
url: process.env.DATABASE_URL || 'file:./keystone-example.db', | ||
}, | ||
lists, | ||
session, | ||
}) | ||
); | ||
``` |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,45 @@ | ||
import { config } from '@keystone-next/keystone/schema'; | ||
import { statelessSessions } from '@keystone-next/keystone/session'; | ||
import { createAuth } from '@keystone-next/auth'; | ||
import { lists } from './schema'; | ||
|
||
// createAuth configures signin functionality based on the config below. Note this only implements | ||
// authentication, i.e signing in as an item using identity and secret fields in a list. Session | ||
// management and access control are controlled independently in the main keystone config. | ||
const { withAuth } = createAuth({ | ||
// This is the list that contains items people can sign in as | ||
listKey: 'Person', | ||
// The identity field is typically a username or email address | ||
identityField: 'email', | ||
// The secret field must be a password type field | ||
secretField: 'password', | ||
|
||
// initFirstItem turns on the "First User" experience, which prompts you to create a new user | ||
// when there are no items in the list yet | ||
initFirstItem: { | ||
// These fields are collected in the "Create First User" form | ||
fields: ['name', 'email', 'password'], | ||
}, | ||
}); | ||
|
||
// Stateless sessions will store the listKey and itemId of the signed-in user in a cookie. | ||
// This session object will be made availble on the context object used in hooks, access-control, | ||
// resolvers, etc. | ||
const session = statelessSessions({ | ||
// The session secret is used to encrypt cookie data (should be an environment variable) | ||
secret: '-- EXAMPLE COOKIE SECRET; CHANGE ME --', | ||
}); | ||
|
||
// We wrap our config using the withAuth function. This will inject all | ||
// the extra config required to add support for authentication in our system. | ||
export default withAuth( | ||
config({ | ||
db: { | ||
provider: 'sqlite', | ||
url: process.env.DATABASE_URL || 'file:./keystone-example.db', | ||
}, | ||
lists, | ||
// We add our session configuration to the system here. | ||
session, | ||
}) | ||
); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,23 @@ | ||
{ | ||
"name": "@keystone-next/example-with-auth", | ||
"version": "0.0.0", | ||
"private": true, | ||
"license": "MIT", | ||
"scripts": { | ||
"dev": "keystone-next dev", | ||
"start": "keystone-next start", | ||
"build": "keystone-next build" | ||
}, | ||
"dependencies": { | ||
"@keystone-next/auth": "^23.0.0", | ||
"@keystone-next/fields": "^8.0.0", | ||
"@keystone-next/keystone": "^17.0.0" | ||
}, | ||
"devDependencies": { | ||
"typescript": "^4.2.4" | ||
}, | ||
"engines": { | ||
"node": ">=v12.13.1" | ||
}, | ||
"repository": "https://github.com/keystonejs/keystone/tree/master/examples/with-auth" | ||
} |
Oops, something went wrong.
5606e59
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Successfully deployed to the following URLs: