I am quite new to React, I got a starter kit which has next.js for authentication in React.
I want to restrict access to admin routes when a user accesses them.
I have two roles, admin
and user
, which gets stored in session after successful login.
The _app.jsx inside pages folder looks like this.
/**
* Custom Next.js App
*
* @see https://nextjs.org/docs#custom-app
*/
import React from 'react'
import Head from 'next/head'
import { NextAuth } from 'next-auth/client'
import withRedux from 'next-redux-wrapper'
import NextSeo from 'next-seo'
import App, { Container as NextContainer } from 'next/app'
import { Provider as ReduxProvider } from 'react-redux'
import { Favicon, GTMScript, WebFonts } from '../components/head'
import { AuthUserProvider } from '../contexts/AuthUserContext'
import makeSEO from '../lib/seo'
import makeStore from '../lib/store'
// Global CSS from SCSS (compiles to style.css in _document)
import '../styles/globals.scss'
class CustomApp extends App {
static async getInitialProps({ Component, ctx }) {
let pageProps = {}
ctx.session = await NextAuth.init({ req: ctx.req })
if (Component.getInitialProps) {
pageProps = await Component.getInitialProps(ctx)
}
return {
pageProps,
seo: makeSEO(ctx.req),
session: ctx.session,
}
}
componentDidMount() {
// picturefill for <picture> and srcset support in older browsers
// eslint-disable-next-line global-require
if (process.browser) require('picturefill')
}
render() {
const { Component, pageProps, seo, session, store } = this.props
return (
<NextContainer>
{
// to keep <Head/> items de-duped we should use next/head in _app.jsx
// @see https://github.com/zeit/next.js/issues/6919
}
<Head>
<meta
name="viewport"
content="width=device-width, initial-scale=1, minimal-ui"
/>
<WebFonts />
<Favicon />
<GTMScript />
</Head>
<ReduxProvider store={store}>
<AuthUserProvider session={session}>
<NextSeo config={seo} />
<Component {...pageProps} />
</AuthUserProvider>
</ReduxProvider>
</NextContainer>
)
}
}
export default withRedux(makeStore)(CustomApp)
Can anyone guide me on what to do in order to make the routes accessible as per the role?
2
Answers
I was able to get roles working with next-auth and useSession. Hopefully, this helps you as well.
models/index.js
models/User.js
pages/api/auth/[…nextauth].js
Usage – in JSX
Github Thread
Here’s how I have done it.
File: _app.js
The logic is to fetch user with role info and check it and render accordingly. If page props has related keys (protected: true, userTypes: ["Admin"]), it is going to be protected from unauthorized access.
Page.tsx
This page is protected. If you do not use them like props: {}, it will not be protected and normal users will access the page.
Css file