如何使用Okta保护Gatsby网站的一部分

问题描述 投票:0回答:1

我开发了一个使用Netlify CMS创建博客的Gatsby应用程序。现在,我想添加一个使用Okta进行身份验证的“帐户”部分。我观看了Add authentication to your apps with Okta并尝试在那里实现逻辑。我可以使用它,但是当需要身份验证时,我很难渲染Sign-In Widget。

我遇到的问题是,当我点击/ account端点时,Okta的登录小部件无法显示。这是帐户页面:

import React from 'react'
import { Router } from '@reach/router'
import { Link } from 'gatsby'

const Home = () => <p>Home</p>;
const Settings = () => <p>Settings</p>;

const isAuthenticated = () => {
  if (typeof window !== 'undefined') {
    return localStorage.getItem('isAuthenticated') === 'true';
  } else {
    return false;
  }
};

const Account = () => {
  if (!isAuthenticated()) {
    return (
      <>
        <p>Please sign in to continue...</p>
        <div id="signIn"/>
      </>
    );
  }

  return (
    <>
      <nav>
        <Link to="/">Home</Link>{' '}
        <Link to="/account">My Account</Link>{' '}
        <Link to="/account/settings">Settings</Link>{' '}
      </nav>
      <h1>My Account</h1>
      <Router>
        <Home path="/account"/>
        <Settings path="/account/settings"/>
      </Router>
    </>
  )
};

export default Account

[您可以看到当用户未登录时会显示<div id="signIn"/>。在gatsby-browser.js中,我具有呈现登录小部件并在用户登录时显示用户信息的逻辑。

import OktaSignIn from '@okta/okta-signin-widget';
import '@okta/okta-signin-widget/dist/css/okta-sign-in.min.css';
import React from 'react';
import { navigate } from '@reach/router';

const config = {
  baseUrl: 'https://dev-133320.okta.com',
  logo: '//logo.clearbit.com/gatsbyjs.org',
  redirectUri: window.location.origin + '/account',
  clientId: '0oa2apgdomrOSH74w357',
  el: '#signIn',
  authParams: {
    pkce: true,
    responseType: ['token', 'id_token'],
  }
};

class AuthWrapper extends React.Component {

  constructor(props) {
    super(props);

    this.state = {
      user: false
    };

    this.signIn = new OktaSignIn(config);
    this.logout = this.logout.bind(this);
  }

  async componentDidMount() {
    const authClient = this.signIn.authClient;
    const session = await authClient.session.get();
    console.log('session.status', session.status);
    // Session exists, show logged in state.
    if (session.status === 'ACTIVE') {
      // clear parameters from browser window
      window.location.hash = '';
      // set username in state
      this.setState({user: session.login});
      localStorage.setItem('isAuthenticated', 'true');
      // get access and ID tokens
      authClient.token.getWithoutPrompt({
        scopes: ['openid', 'email', 'profile'],
      }).then((tokens) => {
        tokens.forEach(token => {
          if (token.idToken) {
            authClient.tokenManager.add('idToken', token);
          }
          if (token.accessToken) {
            authClient.tokenManager.add('accessToken', token);
          }
        });

        // Say hello to the person who just signed in
        authClient.tokenManager.get('idToken').then(idToken => {
          console.log(`Hello, ${idToken.claims.name} (${idToken.claims.email})`);
        });
      }).catch(error => console.error(error));
      return;
    }
    // todo: figure out why it won't display after logout
    this.signIn.renderEl({el: '#signIn'})
  }

  logout = () => {
    this.signIn.authClient.signOut().then((error) => {
      if (error) {
        console.error(error);
        return;
      }
      localStorage.setItem('isAuthenticated', 'false');
      this.setState({user: false});
      navigate('/');
    })
  };

  render() {
    return (
      <React.Fragment>
        {this.state.user ? (
          <React.Fragment>
            <p>Welcome, {this.state.user}. <button onClick={this.logout}>Logout</button></p>
          </React.Fragment>
        ) : null}
        {this.props.children}
      </React.Fragment>
    )
  }
}

export const wrapRootElement = ({element}) => (
  <AuthWrapper>{element}</AuthWrapper>
);

我发现,唯一有效的方法是直接点击http://localhost:8000/account,或者到达目的地后刷新。我相信这是因为在<div id="signIn"/>中执行componentDidMount()gatsby-browser.js不存在。

我尝试将wrapRootElement中的wrapPageElement更改为gatsby-browser.js。根据我与之交谈的Gatsby专家的说法,当路线更改时,此[[does重新安装。我尝试将一些日志记录添加到componentDidMount(),但导航更改时似乎不会触发。我相信,如果这样做的话,可以解决我的问题。

任何想法如何将Okta与Gatsby集成在一起,以便在需要身份验证时呈现Okid。您可以在https://github.com/oktadeveloper/okta-gatsby-netlify-cms-example的GitHub上找到我的项目。
authentication gatsby okta
1个回答
0
投票
我在Gatsby项目上从事类似的工作,本周我要为Okta编写一个isAuthenticated / isLoggedIn值的提供程序,并研究如何将auth prop传递到到达路由器。我将继续我的发现👍
© www.soinside.com 2019 - 2024. All rights reserved.