[英]Role based routes in next.js in React
我对 React 很陌生,我有一个入门套件,其中包含用于在 React 中进行身份验证的 next.js。 当用户访问管理员路由时,我想限制对它们的访问。
我有两个角色, admin
和user
,它们在成功登录后存储在会话中。
_app.jsx inside pages 文件夹如下所示。
/**
* 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)
任何人都可以指导我如何根据角色访问路线吗?
我能够获得使用 next-auth 和useSession 的角色。 希望这对您也有帮助。
模型/index.js
import User, { UserSchema } from "./User"
export default {
User: {
model: User,
schema: UserSchema
}
}
模型/User.js
import Adapters from "next-auth/adapters"
// Extend the built-in models using class inheritance
export default class User extends Adapters.TypeORM.Models.User.model {
constructor(name, email, image, emailVerified, roles) {
super(name, email, image, emailVerified)
if (roles) { this.roles = roles}
}
}
export const UserSchema = {
name: "User",
target: User,
columns: {
...Adapters.TypeORM.Models.User.schema.columns,
roles: {
type: "varchar",
nullable: true
},
},
}
页面/api/auth/[...nextauth].js
import NextAuth from 'next-auth'
import Providers from 'next-auth/providers'
import Adapters from 'next-auth/adapters'
import Models from '../../../models'
export default NextAuth({
// @link https://next-auth.js.org/configuration/providers
providers: [
Providers.Google({
clientId: process.env.GOOGLE_ID,
clientSecret: process.env.GOOGLE_SECRET
})
],
// @link https://next-auth.js.org/tutorials/typeorm-custom-models
adapter: Adapters.TypeORM.Adapter(
process.env.DATABASE_URL,
{
models: {
User: Models.User
}
}
),
session: { jwt: true },
callbacks: {
async jwt(token, user, account, profile, isNewUser) {
if (account?.accessToken) {
token.accessToken = account.accessToken
}
if (user?.roles) {
token.roles = user.roles
}
return token
},
async session(session, token) {
if(token?.accessToken) {
session.accessToken = token.accessToken
}
if (token?.roles) {
session.user.roles = token.roles
}
return session
}
}
});
用法 - 在 JSX 中
{!session && sessionLoading && <p>Loading...</p>}
{!session && !sessionLoading && <p>Access Denied - Not logged in</p> }
{ session && !sessionLoading && !session.user?.roles?.includes("Verified") && <p>Access Denied - Unverified</p> }
{ session && !sessionLoading && session.user?.roles?.includes("Verified") && <>
<p>Stuff for verified users</p>
{session.user.roles && session.user.roles.includes("Admin") && <>
<button id="doSomething">Admin Only</button>
</>}
<p>More stuff for verified users</p>
</>}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.