Skip to content

Commit

Permalink
feat(provider): forward request to authorize (#1979)
Browse files Browse the repository at this point in the history
* feat/add-request-to-credentials-authorize

* Update src/server/routes/callback.js

Co-authored-by: Balázs Orbán <info@balazsorban.com>

* Update types/providers.d.ts

Co-authored-by: Balázs Orbán <info@balazsorban.com>

* Update www/docs/providers/credentials.md

Co-authored-by: Balázs Orbán <info@balazsorban.com>

* Update www/docs

* Update test app

Co-authored-by: Balázs Orbán <info@balazsorban.com>
  • Loading branch information
igordanchenko and balazsorban44 authored May 15, 2021
1 parent eba79f4 commit 0fae0c7
Show file tree
Hide file tree
Showing 6 changed files with 21 additions and 17 deletions.
2 changes: 1 addition & 1 deletion app/pages/api/auth/[...nextauth].js
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ export default NextAuth({
credentials: {
password: { label: "Password", type: "password" },
},
async authorize(credentials) {
async authorize(credentials, req) {
if (credentials.password === "password") {
return {
id: 1,
Expand Down
2 changes: 1 addition & 1 deletion src/server/routes/callback.js
Original file line number Diff line number Diff line change
Expand Up @@ -336,7 +336,7 @@ export default async function callback(req, res) {
let userObjectReturnedFromAuthorizeHandler
try {
userObjectReturnedFromAuthorizeHandler = await provider.authorize(
credentials
credentials, {...req, options: {}, cookies: {}}
)
if (!userObjectReturnedFromAuthorizeHandler) {
return res
Expand Down
4 changes: 2 additions & 2 deletions types/providers.d.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { Profile, TokenSet, User } from "."
import { Awaitable } from "./internals/utils"
import { Awaitable, NextApiRequest } from "./internals/utils"

export type ProviderType = "oauth" | "email" | "credentials"

Expand Down Expand Up @@ -115,7 +115,7 @@ interface CredentialsConfig<C extends Record<string, CredentialInput> = {}>
extends CommonProviderOptions {
type: "credentials"
credentials: C
authorize(credentials: Record<keyof C, string>): Awaitable<User | null>
authorize(credentials: Record<keyof C, string>, req: NextApiRequest): Awaitable<User | null>
}

export type CredentialsProvider = (
Expand Down
20 changes: 11 additions & 9 deletions www/docs/configuration/providers.md
Original file line number Diff line number Diff line change
Expand Up @@ -254,12 +254,14 @@ providers: [
username: { label: "Username", type: "text", placeholder: "jsmith" },
password: { label: "Password", type: "password" }
},
async authorize(credentials) {
const user = (credentials) => {
async authorize(credentials, req) {
const user = (credentials, req) => {
// You need to provide your own logic here that takes the credentials
// submitted and returns either a object representing a user or value
// that is false/null if the credentials are invalid.
// e.g. return { id: 1, name: 'J Smith', email: 'jsmith@example.com' }
// You can also use the request object to obtain additional parameters
// (i.e., the request IP address)
return null
}
if (user) {
Expand All @@ -282,10 +284,10 @@ The Credentials provider can only be used if JSON Web Tokens are enabled for ses

### Options

| Name | Description | Type | Required |
| :---------: | :-----------------------------------------------: | :------------------------------: | :------: |
| id | Unique ID for the provider | `string` | Yes |
| name | Descriptive name for the provider | `string` | Yes |
| type | Type of provider, in this case `credentials` | `"credentials"` | Yes |
| credentials | The credentials to sign-in with | `Object` | Yes |
| authorize | Callback to execute once user is to be authorized | `(credentials) => Promise<User>` | Yes |
| Name | Description | Type | Required |
| :---------: | :-----------------------------------------------: | :-----------------------------------: | :------: |
| id | Unique ID for the provider | `string` | Yes |
| name | Descriptive name for the provider | `string` | Yes |
| type | Type of provider, in this case `credentials` | `"credentials"` | Yes |
| credentials | The credentials to sign-in with | `Object` | Yes |
| authorize | Callback to execute once user is to be authorized | `(credentials, req) => Promise<User>` | Yes |
8 changes: 5 additions & 3 deletions www/docs/providers/credentials.md
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,8 @@ The Credentials provider is specified like other providers, except that you need

If you throw an Error, the user will be sent to the error page with the error message as a query parameter. If throw a URL (a string), the user will be redirected to the URL.

The Credentials provider's `authorize()` method also provides the request object as the second parameter (see example below).

```js title="pages/api/auth/[...nextauth].js"
import Providers from `next-auth/providers`
...
Expand All @@ -53,7 +55,7 @@ providers: [
username: { label: "Username", type: "text", placeholder: "jsmith" },
password: { label: "Password", type: "password" }
},
async authorize(credentials) {
async authorize(credentials, req) {
// Add logic here to look up the user from the credentials supplied
const user = { id: 1, name: 'J Smith', email: 'jsmith@example.com' }

Expand Down Expand Up @@ -90,7 +92,7 @@ As with all providers, the order you specify them is the order they are displaye
Providers.Credentials({
id: 'domain-login',
name: "Domain Account",
async authorize(credentials) {
async authorize(credentials, req) {
const user = { /* add function to get user */ }
return user
},
Expand All @@ -103,7 +105,7 @@ As with all providers, the order you specify them is the order they are displaye
Providers.Credentials({
id: 'intranet-credentials',
name: "Two Factor Auth",
async authorize(credentials) {
async authorize(credentials, req) {
const user = { /* add function to get user */ }
return user
},
Expand Down
2 changes: 1 addition & 1 deletion www/docs/tutorials/ldap-auth.md
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ export default NextAuth({
username: { label: "DN", type: "text", placeholder: "" },
password: { label: "Password", type: "password" },
},
async authorize(credentials) {
async authorize(credentials, req) {
// You might want to pull this call out so we're not making a new LDAP client on every login attemp
const client = ldap.createClient({
url: process.env.LDAP_URI,
Expand Down

1 comment on commit 0fae0c7

@vercel
Copy link

@vercel vercel bot commented on 0fae0c7 May 15, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please sign in to comment.