Compare commits

...

1 Commits

Author SHA1 Message Date
Igor Danchenko
0fae0c7a8e feat(provider): forward request to authorize (#1979)
* 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>
2021-05-15 03:00:39 +02:00
6 changed files with 21 additions and 17 deletions

View File

@@ -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,

View File

@@ -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

View File

@@ -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"
@@ -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 = (

View File

@@ -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) {
@@ -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 |

View File

@@ -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`
...
@@ -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' }
@@ -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
},
@@ -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
},

View File

@@ -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,