Home
Basics
Introduction Environment setup Project structure Pages CSS in NextJS JavaScript in NextJS Layouts Data Fetching Routing API Routes Metadata and SEO Environment Variables OptimizationsAdvanced
Dynamic Importing Blog using md files Authentication in NextJS Mongodb and NextJS Stripe and NextJSMiscellaneous
Deploying NextJS app on Heroku NextJS Templates NextJS Interview QnAAuthentication in NextJS
Authentication Scheme
Authentication means verifying that user is valid. Different providers are used for authemtication as mentioned below.- [userid + password==credential provider]
- [social media login - goog/fb/github provider - Oauth2]
- Email Provider
- - After login, server creates sessions and sends session id to the client via cookie. User details are mapped to session id on server
- - Browser automatically sends the session id via cookie on every subsequent request
- - you can invalidate session
- - Generally used in banking apps
- - After successful login, server creates JWT token and sends to the client.
- - Client can send the token in authorization header on every request.
- - Nothing stored on server.
- - need refresh token to keep user logged in
Using libraries
Passportjs - just a library to above things next-authUsing auth service
auth0 - Amazon incognitoNext-Auth
High level steps are mentioned below.- Dependencies - next-auth and mongodb
- Providers - Generate provider (google, github or facebook) client id and secret
- next auth handler endpoint - Add api/auth/[...nextauth].js endpoint
- Then you should be able to go to this sign in page at api/auth/signin
- Add SessionProvider in _app.tsx
- Use session at client side
- Use session at Server Side
- Use adapter if you want to store session and user data in db e.g. mongodb
Dependencies
First you need to install below dependencies
npm i --save next-auth mongodb @next-auth/mongodb-adapter
Provider settings - e.g. github oauth app
- Create oauth app on github at https://github.com/settings/developers
- callback url - /api/auth/callback/github
- Get client id and secret
next-auth handler endpoint
In .env.local file, store the secrets.- provider_client_id
- provider_client_secret
- NEXTAUTH_URL
- auth_secret
- jwt_secret
import NextAuth from 'next-auth'
import AppleProvider from 'next-auth/providers/apple'
import GitHubProvider from 'next-auth/providers/github'
export default (req,res) => NextAuth(req,res, {
providers : [
GitHubProvider({
clientId : process.env.githubClientId,
clientSecret : process.env.githubClientSecret
})],
debug : true,
secret : "authsecrett",
jwt : {
secret : "mysehdihfu"
}
})
Test that api handler is working
Just go to api/auth/signin and provider login buttons should be displayed.Add SessionProvider in _app.tsx
You can use the context provider
import { Layout } from '../components/Layout'
import '../styles/globals.css'
import '../node_modules/highlight.js/styles/magula.css'
import type { AppProps } from 'next/app'
import { SessionProvider } from "next-auth/react"
function MyApp({ Component, pageProps: { session, ...pageProps } }: AppProps) {
return (
<SessionProvider session={session} refetchInterval={5 * 60}>
<Layout>
<Component {...pageProps} />
</Layout>
</SessionProvider>
)
}
export default MyApp
Use Session at client side
import { useSession, getSession } from "next-auth/react"
export default function Page() {
const { data: session, status } = useSession()
if (status === "loading") {
return <p>Loading...</p>
}
if (status === "unauthenticated") {
return <p>Access Denied</p>
}
return (
<>
<h1>Protected Page</h1>
<p>You can view this page because you are signed in.</p>
</>
)
}
Get session data at client side
import { useSession } from 'next-auth/react'
const { data: session, status } = useSession()
if (status==="loading"){
// return (<span>Loading</span>)
return ("<span>Loading</span>")
}
//data: Session / undefined / null
if (!session){
return (<span>Please sign in first</span>)
}
if (session){
return (<>{JSON.stringify(session)}</>)
}
Protecting api routes on server
import { getSession } from "next-auth/react"
export default async (req, res) => {
const session = await getSession({ req })
if (session) {
// Signed in
console.log("Session", JSON.stringify(session, null, 2))
} else {
// Not Signed in
res.status(401)
}
res.end()
}
Getting token from server
import { getToken } from "next-auth/jwt"
const secret = process.env.SECRET
export default async (req, res) => {
const token = await getToken({ req, secret })
if (token) {
// Signed in
console.log("JSON Web Token", JSON.stringify(token, null, 2))
} else {
// Not Signed in
res.status(401)
}
res.end()
}
Database adapter
So far we have not stored session or user information in database. So let's do it now. npm install @prisma/client @next-auth/prisma-adapter npm install prisma --save-devWeb development and Automation testing
solutions delivered!!