Nextjs: Oauth and Credentials authentication with NextAuth - Part 2
Tags: nextjs, react, webdev, beginners
Published: 2022-06-28 10:16:37

Welcome to the second part of NextJs with NextAuth, In the first part we've seen how to integrate Oauth2 authentication to your application, Here is the first part if you haven't seen it 

{% embed https://dev.to/m0nm/nextjs-oauth-and-credentials-authentication-with-nextauth-553h %}

Today we are going to look at how to implement username and password authentication. Let's get started! 

If we take a look at NextAuth big list of providers we have a Credentials provider. The Credentials provider allows you to handle signing in with  credentials, such as a username and password, domain, or two factor authentication or hardware device.

Credentials provider is used when you have a backend database setup you wish to authenticate against.

The default drawback is that the authenticated users sessions can not persisted in the database. (because the credentials provider uses the JWT strategy, Only other Oauth providers sessions can be stored through a database adapter)

## Let's Get Started
 create a nextjs app :
  `npx create-next-app credentials-auth`

 install NextAuth: 
 `npm i next-auth`

inside `pages/_app.js` add `SessionProvider`

```jsx
  
import { SessionProvider } from "next-auth/react"

export default function App({ Component, pageProps: { session, ...pageProps }}) { 

	return (
		<SessionProvider session={session}> 
			<Component {...pageProps} />
		</SessionProvider> 
	 )
	}
```

And finally add the api route in `pages/api/auth/[...nextauth].js`  


## Setting up Credential Provider

Now we're ready to set up the credentials provider, So inside `[nextauth].js` Add this:

```js
import NextAuth from "next-auth"
import CredentialsProvider from "next-auth/providers/credentials";

export default NextAuth({ 

	// any secret word like: "i am a stegosaurus"
	secret: process.env.SECRET,

	// enabe JWT
	session: {
		strategy: "jwt",
	},

	providers = [

		CredentialsProvider({ 
		// the button text displayed on the sign in form
			name: "Sign In With Credentials",
		})
	
	]

})
```


## Adding the credentials fields
Now specify the input fields that would be displayed on the default sign in form

you can use your custom login page as well 

```js
	...
		credentials: {
		
			username: { 
							label: "Username", 
							type: "text", 
                     placeholder:"Enter Your Username..." 
                   },

			password: { 
							label: "Password", 
							type: "password", 
                     placeholder:"Enter Your Password..." 
                   }
		}
	...
```

Here's how the form looks like 


![login form](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/3f6kudo369gptx7ijk5c.png)


## The authorize function 

Now we need to setup the authorize function 

The authorize function is where we validate the user input against the database records

Inside the authorize function you add authentication logic to look for the user, compare the passwords... 

For example: 

```js
	...
		async authorize(credentials, req) { 
		
			const res = await fetch('www.server.com', {
				method: "post",
				
				headers: {
								"Content-Type": "application/json",
							},
							
				body: JSON.stringify({
						username: req.body.username
						password: req.body.password
				})
			
			})
			// and then you may or may not get the user 
			const user = await res.json()
		
		}
	...
```

Now the important part: the data you return from the authorize function:

**If you return a user object**

Then it means the credentials are valid, The returned object will be persisted to the JSON Web Token and the user will be signed in

**If you return `null`**

 then an error will be displayed advising the user to check their details.

**If you throw an error**

the user will be sent to the error page with the error message as a query parameter.

```js
...

async authorize() {

	// if credentials are valid
	if (user) {  
		return user  
	} else {
		return null
	}
}
...
```

And that's it! 

**Here is the full code:** 

```js
import NextAuth from "next-auth"
import CredentialsProvider from "next-auth/providers/credentials";

export default NextAuth({ 

	// any secret word like: "i am a stegosaurus"
	secret: process.env.SECRET,

	// enable JWT
	session: {
		strategy: "jwt",
	},

	providers: [

		CredentialsProvider({ 
	
			// the button text displayed on the sign in form
			// so this would be: sign in with Credentials
			name: "Credentials",
	
			// the input fields on the default sign in form
			// you can use your custom login page instead 
			credentials: {
			
				username: { 
								label: "Username", 
								type: "text", 
	                     placeholder:"Enter Your Username..." 
	                   },
	
				password: { 
								label: "Password", 
								type: "password", 
	                     placeholder:"Enter Your Password..." 
	                   }
			},
	
		// The authorize function is where we validate the user input 
		// against the database records
		async authorize(credentials, req) { 
		
			// Here you add authentication logic: 
			// look for the user, compare the passwords... 
			const res = await fetch('www.server.com', {
				method: "post",
				
				headers: {
								"Content-Type": "application/json",
							},
							
				body: JSON.stringify({
						username: req.body.username,
						password: req.body.password
				})
			
			})
			
			// and then you may or may not get the user 
			const user = await res.json()
	
			// if credentials are valid
			if (user) {  
					return user  
				} 
			
			else {
				// if not
				return null;
				}
		}
	
	})

	]
})
```

## Conclusion 

We've reached the end of this post, Hopefully it was helpful to you. If you liked this post then consider giving me a  <span style="color: red">❤️</span>, And don't forget to follow me if you want more of my content! 

Till next time, Happy coding!