反应-Auth0?工作!反应 - 终极版 - Auth0?我正在失去理智:/

时间:2018-06-18 02:21:28

标签: javascript redux react-redux auth0

这是一个非常长的帖子,但我真的需要一些帮助:/

如果有人能够提供帮助,我将永远感激。

我已经设法让Auth0正在为我正在努力的应用程序工作。它是一个Overwatch SR跟踪器,基本上只是一个电子表格,所以当我制作它时,我并不太关心保护后端路由。那里没有私人信息。

我的应用程序状态/道具网络变得太复杂而无法管理,并且通过实现redux的过程我根本无法让它工作。我已经在这里呆了三天了,而且我的想法已经不多了。我目前的Auth设置是否需要Thunk才能执行此操作?我会想象它是异步的,因为它需要得到不存在的东西。

当然我是初级开发人员,并且没有太多的身份验证经验。有人可以看看我的工作反应应用程序,并指导我的方向,我可能需要做什么来设置redux?我确实对redux流量有所了解,所以如果向我解释了正确的方法,我觉得我可能会得到它。

这里有一些代码:

我的Auth.js文件:

/*eslint no-restricted-globals: 0 */
import auth0 from "auth0-js";
import jwtDecode from 'jwt-decode';

const LOGIN_SUCCESS_PAGE = '/menu';
const LOGIN_FAILURE_PAGE = '/';

export default class Auth {
  auth0 = new auth0.WebAuth({
    domain: "redacted.auth0.com",
    clientID: "redacted",
    redirectUri: "http://localhost:3000/callback",
    audience: "https://redacted.auth0.com/userinfo",
    responseType: "token id_token",
    scope: "openid profile"
  });

  constructor() {
    this.login = this.login.bind(this);
  }

  login() {
    this.auth0.authorize();
  }

  handleAuthentication() {
    this.auth0.parseHash((err, authResults) => {
        if (authResults && authResuslts.accessToken && authResults.idToken) {
            let expiresAt = JSON.stringify((authResults.expiresIn) * 1000 + new Date().getTime());
            localStorage.setItem("access_token", authResults.accessToken);
            localStorage.setItem("id_token", authResults.idToken);
            localStorage.setItem("expires_at", expiresAt);
            location.hash = "";
            location.pathname = LOGIN_SUCCESS_PAGE;
        } else if (err) {
            location.pathname = LOGIN_FAILURE_PAGE;
            console.log(err);
        }
    });
  }

  isAuthenticated() {
    let expiresAt = JSON.parse(localStorage.getItem('expires_at'));
    return new Date().getTime() < expiresAt;
  }
  logout() {
      localStorage.removeItem("access_token");
      localStorage.removeItem("id_token");
      localStorage.removeItem('expires_at');
      location.pathname = LOGIN_FAILURE_PAGE;
  }

  getProfile() {
    if (localStorage.getItem("id_token")) {
        console.log(jwtDecode(localStorage.getItem("id_token")))
        console.log(localStorage.getItem("id_token"));
        return jwtDecode(localStorage.getItem("id_token"));
    } else {
        return {
          name: 'Anon',
          nickname: 'Anon',
          picture: 'placeholder',
          uid: null,
        }
    }
  }
}

我的index.js文件:

import React from 'react';
import ReactDOM from 'react-dom';
import './index.css';
import App from './App';
import registerServiceWorker from './registerServiceWorker';
import Auth from './Auth';
import { BrowserRouter } from 'react-router-dom';

const auth = new Auth();

let state = {};
window.setState = (changes) => {
    state = Object.assign({}, state, changes)
    ReactDOM.render(
        <BrowserRouter>
            <App {...state} />
        </BrowserRouter>,
        document.getElementById('root'));
}

/* eslint no-restricted-globals: 0*/

let getUserProfile = auth.getProfile();

let initialState = {
    owSrTrackInfo: {
        infoSaved: false,
        accounts: [],
    },
    user: getUserProfile,
    location: location.pathname.replace(/^\/?|\/$/g, ""),
    auth,
}

window.setState(initialState);

registerServiceWorker();

我的App.js文件:

import React, { Component } from "react";
import "./App.css";
import Main from "./Components/Main/Main";
import Menu from "./Pages/Menu/Menu";
import NotFound from "./Components/NotFound/NotFound";
import Callback from './Components/Callback/Callback';
import Header from './Components/Header/Header';

class App extends Component {
  render() {
    let mainComponent = "";
    switch (this.props.location) {
      case "":
        mainComponent = <Main {...this.props} />;
        break;
      case "callback":
        mainComponent = <Callback />
        break;
      case "menu":
        mainComponent = this.props.auth.isAuthenticated() ? < Menu {...this.props} /> : <NotFound />;
        break;
      default:
        mainComponent = <NotFound />;
    }

    return (
      <div className="app">

        <Header {...this.props} />
        {mainComponent}
      </div>
    );
  }
}

export default App;

我的Callback.js组件:

import React, {Component} from 'react';
import Auth from '../../Auth'

export default class Callback extends Component {
    componentDidMount() {
        const auth = new Auth();
        auth.handleAuthentication();
    }

    render() {
        return(
            <p className="loading">Loading.....</p>
        )
    }
}

我目前的MAIN.js组件:

import React, { Component } from "react";

export default class Main extends Component {
  render() {
    console.log(this.props.auth.getProfile())
    return (
      <div className="container">
          <div className='container--logged-out'>
          <h1 className="heading u-margin-bottom-small">welcome to redacteds' overwatch sr tracker</h1>
            <p>Hello there {this.props.user.nickname}! Sign in single click or email via Auth0 so we can save your results, and make the app usable by more than one person. I intend for more than one person to use this, so just to launch it and so the app knows your spreadsheet from someone elses I'll tie each user to their own UID. Feel free to come back, log in, and get your spreadsheet for the season back anytime.</p>
          </div>
          <a href="/menu">Go to the app menu!</a>
          <button onClick={() =>this.props.auth.getProfile()}>asdgkljsdngk</button>
      </div>
    );
  }
}

我目前的HEADER.js组件:

import React, { Component } from 'react';

export default class Header extends Component {
    render() {
        return (
            <header className="header">
                <h1 className='header__text'>SR TRACKER</h1>
                {this.props.auth.isAuthenticated() ?
                    <button className='btn btn--logout' onClick={() => this.props.auth.logout()}>Logout</button>
                    :
                    <button className='btn btn--login' onClick={() => this.props.auth.login()}>Login or Sign Up</button>}
            </header>
        )
    }
}

我只想将此身份验证映射到redux存储,而不是与我的应用程序的其余部分一起使用(当执行redux时)我已将其吹走并重新开始多次,但是我对redux流程的概念很简单可能看起来像我使用的这个模板,并成功实施了几次:

redux store:

import { createStore, compose, applyMiddleware } from 'redux';
import { createLogger } from 'redux-logger';
import thunk from 'redux-thunk';

import rootReducer from './reducers/rootReducer';

export default function configureStore(initialState) {
  const middleware = [
    createLogger({
      collapsed: false,
      duration: true,
      diff: true,
    }),
    thunk,
  ];

  const store = createStore(
    rootReducer,
    initialState,
    compose(
      applyMiddleware(...middleware),
      window.devToolsExtension ? window.devToolsExtension() : format => format, // add support for Redux dev tools),
    ),
  );

  return store;
}
动作文件夹中的

actionTypes.js:

const actions = {
  GET_FRIENDS: 'GET_FRIENDS',
  REMOVE_FRIEND: 'REMOVE_FRIEND',

  GET_MOVIES: 'GET_MOVIES',
  GET_MOVIES_SUCCESS: 'GET_MOVIES_SUCCESS',
  GET_MOVIES_FAILURE: 'GET_MOVIES_FAILURE',

  DEVIN_FUN: 'DEVIN_FUN',
};

export default actions;

示例操作页面:

import axios from 'axios';
import actionTypes from './actionTypes';

export const getMoviesSuccess = data => {
  return {
    type: actionTypes.GET_MOVIES_SUCCESS,
    data,
  };
};

export const getMoviesFailure = () => {
  return {
    type: actionTypes.GET_MOVIES_FAILURE,
  };
};

export const devinIsHavingFun = () => {
  return {
    type: actionTypes.DEVIN_FUN,
  };
};

export const retrieveMovies = () => {
  return function(dispatch) {
    const API_KEY = 'trilogy';

    dispatch(devinIsHavingFun());

    axios
      .get(`http://www.omdbapi.com?apikey=${API_KEY}&s=frozen`)
      .then(data => {
        dispatch(getMoviesSuccess(data.data.Search));
      })
      .catch(error => {
        console.log(error);
        dispatch(getMoviesFailure());
      });
  };
};
在reducers文件夹中,

有一些文件,比如initialState.js和root reducer,它们分别如下所示:

initialState.js:

export default {
  friends: [],
  movies: [],
};

rootReducer.js:

import { combineReducers } from 'redux';
import friends from './friendReducer';
import movies from './movieReducer';

const rootReducer = combineReducers({
  friends,
  movies,
});

export default rootReducer;

和示例缩减器:

import actionTypes from '../actions/actionTypes';
import initialState from './initialState';

export default function movieReducer(state = initialState.movies, action) {
  switch (action.type) {
    case actionTypes.GET_MOVIES_SUCCESS: {
      return action.data;
    }
    default: {
      return state;
    }
  }
}

我只是不知道该怎么做。我需要使用thunk吗?我在想这个吗?我把头发拉了出来。

在实现redux时,我也以这种方式连接我的组件:

import React, { Component } from 'react';
import { connect } from 'react-redux';
import { bindActionCreators } from 'redux';
import * as friendActionCreators from './actions/friendActions';
import * as movieActionCreators from './actions/movieActions';

....................
function mapStateToProps(state) {
  return {
    myFriends: state.friends,
    movies: state.movies,
  };
}
function mapDispatchToProps(dispatch) {
  return {
    friendActions: bindActionCreators(friendActionCreators, dispatch),
    movieActions: bindActionCreators(movieActionCreators, dispatch),
  };
}

export default connect(mapStateToProps, mapDispatchToProps)(App);

如果有人能指出我正确的方向,请告诉我。非常感谢你。

0 个答案:

没有答案