- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我正在开发一个reactjs/redux应用程序 - 并使用Java Spring Boot代码库作为API。
我已经有了一个登录系统 - 但我注意到当我刷新页面时 - 身份验证状态丢失了。
我添加了 redux-persist,但它似乎对存储登录状态和恢复体验没有任何影响?
大部分 redux-persist 都位于我的 router.js 上——它是商店/提供程序设置为应用程序的地方。
我不确定用户登录后如何以及在哪里存储状态——我已经公开了登录表单,你可以看到我开始检查 this.props.authData 状态——它会在哪里调用 persistor.reHydrate() 是理想的选择——但是我无法访问这些页面上的持久器或存储?
//router.js
import React, { Component } from 'react'
import { BrowserRouter as Router, Route, Redirect, Switch } from 'react-router-dom'
import createBrowserHistory from 'history/createBrowserHistory'
import { Provider } from 'react-redux'
import { createStore, applyMiddleware } from 'redux'
import thunk from 'redux-thunk';
import {persistStore, autoRehydrate} from 'redux-persist'
import rootReducer from './reducers/rootReducer'
// components
import Login from './components/Login/Login'
import ForgotPassword from './components/ForgotPassword/ForgotPassword'
import RegisterUser from './components/RegisterUser/RegisterUser'
import Home from './components/Home/Home'
import Actions from './components/Actions/Actions'
import AddSDQ from './components/Actions/AddSDQ'
import PastSDQ from './components/PastSDQ/PastSDQ'
import Account from './components/Account/Account'
import Logout from './components/Logout/Logout'
import About from './components/About/About'
import Terms from './components/Terms/Terms'
import Privacy from './components/Privacy/Privacy'
import Error from './components/Error/Error'
import Header from './components/Header/Header'
import Footer from './components/Footer/Footer'
const history = createBrowserHistory()
// add `autoRehydrate` as an enhancer to your store (note: `autoRehydrate` is not a middleware)
const store = createStore(
rootReducer,
applyMiddleware(thunk),
autoRehydrate()
);
const persistor = persistStore(store, {}, () => {
console.log('restored');
})
// we can pass the lang files as props to the routes
// we should have a nested route inside service here to show the other services page
class Routes extends Component {
constructor (props) {
super(props)
/*
this.state = {
rehydrated: false
}*/
//console.log("router level", this.props)
//console.log("state-->", this.state)
}
componentWillMount(){
// begin periodically persisting the store
/*
persistStore(store, {}, () => {
this.setState({ rehydrated: true })
console.log("rehydrated", store);
})*/
}
render () {
console.log("this props", this);
// when the user has logged in - navigate them to the home page
if(this.props.authData){
//this.props.authData.isLogged
//return <Redirect to='/home'/>;
console.log("user logged!!!!!!!!!!!");
//persistor.rehydrate()//calls reducer to rehydrate store
}
const loggedIn = true;//this.state.isLoggedIn;
console.log("rendered store", store);
return (
<Provider store={store}>
<Router history={history}>
<div className='off-canvas-wrap' data-offcanvas>
<div className='inner-wrap'>
<Header transparent />
<Switch>
<Route path='/home' component={Home} />
<Route path='/past-sdq' component={PastSDQ} />
<Route path='/actions' component={Actions} />
<Route path='/add-sdq' component={AddSDQ} />
<Route path='/account' component={Account} />
<Route path='/about' component={About} />
<Route path='/terms' component={Terms} />
<Route path='/privacy' component={Privacy} />
<Route path='/login' component={Login} />
<Route path='/logout' component={Logout} />
<Route path='/forgot-password' component={ForgotPassword} />
<Route path='/register-user' component={RegisterUser} />
{/*<Route path='/api/:serviceRequest' />*/}
<Route exact path="/" render={() => ( loggedIn ? ( <Home/> ) : ( <Redirect to="/login"/> ) )} />
<Route component={Error} />
</Switch>
<Footer transparent />
</div>
</div>
</Router>
</Provider>
)
}
}
export default Routes
//rootReducer.js
import { combineReducers } from 'redux'
import { reducer as formReducer } from 'redux-form'
import { authReducer } from './authReducer'
import { regReducer } from './regReducer'
import { forgotReducer } from './forgotReducer'
import { homeReducer } from './homeReducer'
import { editProfileReducer } from './editProfileReducer'
import { initProfileReducer } from './initProfileReducer'
import { editFollowUpReducer } from './editFollowUpReducer'
import { initFollowUpReducer } from './initFollowUpReducer'
import { addSDQReducer } from './addSDQReducer'
import { pastSDQReducer } from './pastSDQReducer'
import { rehydrateReducer } from './rehydrateReducer'
const rootReducer = combineReducers({
form: formReducer,
auth: authReducer,
reg: regReducer,
forgot: forgotReducer,
home: homeReducer,
editProfile: editProfileReducer,
initProfile: initProfileReducer,
editFollowUp: editFollowUpReducer,
initFollowUp: initFollowUpReducer,
addSDQ: addSDQReducer,
pastSDQ: pastSDQReducer,
rehydrate: rehydrateReducer
})
export default rootReducer
//re HydroReducer.js
import {REHYDRATE} from 'redux-persist/constants'
export function rehydrateReducer (state = {}, action) {
//console.log('reducer REHYDRATE act', action)
switch (action.type) {
case REHYDRATE:
return {...state, data: action.payload};
default:
return {...state}
}
}
//登录.js
import React, { Component } from 'react'
import { withRouter, Redirect } from 'react-router-dom';
//import { withRouter, Redirect } from 'react-router-dom';
import { connect } from 'react-redux';
import { bindActionCreators } from 'redux';
import { fetchAuthentication } from '../../actions/authAction';
import {persistStore} from 'redux-persist'
import { Row, Col } from 'antd';
// components
import LoginSyncValidationForm from './LoginSyncValidationForm'
import '../../forms.scss';
// this is a class because it needs state
class Login extends Component {
constructor(props, context) {
super(props, context);
this.submit = this.submit.bind(this);
}
/*
static propTypes = {
isDark: React.PropTypes.bool
}
static defaultProps = {
isDark: false
}
*/
componentDidMount() {
//document.body.classList.toggle('darkClass', this.props.isDark)
}
componentWillReceiveProps(nextProps) {
//document.body.classList.toggle('darkClass', nextProps.isDark)
}
componentWillMount () {
document.body.classList.add('screenbackground');
}
componentWillUnmount() {
document.body.classList.remove('screenbackground');
}
submit(data) {
this.props.fetchAuthentication(data);
}
render() {
var errorPlaceholder = "";
//console.log("authss-->", this.props.authData);
if(this.props.authData.data){
//console.log("status--<", this.props.authData.data.data.status);
//if error from server side show the message
if(this.props.authData.data.data.status !== "success"){
errorPlaceholder = this.props.authData.data.data.msg;
}
}
// when the user has logged in - navigate them to the home page
if(this.props.authData.isLogged){
//return <Redirect to='/home'/>;
//persistor.rehydrate()//calls reducer to rehydrate store
}
return (
<div className="Page form-components light">
<h2>Login</h2>
<Row>
<Col xs={24} sm={24} md={10}>
<p>Welcome to the SLAM SDQ tracker. Because you are accessing sensitive info, you need to verify your identity using our secure login system. This will not only protect your data, but will provide a platform where you can be in control of your progress. Your unique identification number has been sent to you by e-mail. Use it to login. If you have not created an account yet or have forgotten your password, please use the links below to complete the desired action.</p>
</Col>
<Col xs={24} sm={24} md={24}>
<Row>
<Col xs={24} sm={24} md={6}>
<LoginSyncValidationForm onSubmit={this.submit} />
</Col>
</Row>
</Col>
{errorPlaceholder.length > 0 &&
<Col xs={24} sm={24} md={24}>
{errorPlaceholder}
</Col>
}
</Row>
<div className="shell" />
<div className="screen-background login"/>
</div>
)
}
}
function mapStateToProps(state) {
return {
authData: state.auth
};
}
function mapDispatchToProps(dispatch) {
return bindActionCreators({ fetchAuthentication }, dispatch);
}
export default withRouter(connect(mapStateToProps, mapDispatchToProps)(Login))
<小时/>
更新 1:2017 年 9 月 14 日
这就是我的 authAction.js 的样子
//authAction.js
import axios from 'axios';
export const FETCH_AUTH_SUCCESS = 'FETCH_AUTH_SUCCESS'
export const FETCH_AUTH_FAILURE = 'FETCH_AUTH_FAILURE'
export const FETCH_AUTH_CLEAR = 'FETCH_AUTH_CLEAR'
export function authSuccess(response) {
return {
type: FETCH_AUTH_SUCCESS,
payload: response
}
}
export function authFail(response) {
return {
type: FETCH_AUTH_FAILURE,
payload: response
}
}
export function authClear() {
return {
type: FETCH_AUTH_CLEAR,
payload: null
}
}
export function fetchAuthentication(data) {
let url = 'http://localhost:8080/login';
return function (dispatch) {
//axios.post(url, data)
axios.get(url, {
params: data
})
.then(function (response) {
console.log(response);
if(response.data.status === "success"){
dispatch(authSuccess(response));
}
else{
// fail - user not found for example
dispatch(authFail(response));
}
})
.catch(function (error) {
//console.log(error);
dispatch(authFail(error));
});
}
}
export function clearAuthentication() {
let url = 'http://localhost:8080/logout';
return function (dispatch) {
//axios.post(url, data)
axios.get(url)
.then(function (response) {
console.log(response);
if(response.data.status === "success"){
dispatch(authClear(response));
}
else{
// fail - user not found for example
dispatch(authFail(response));
}
})
.catch(function (error) {
//console.log(error);
dispatch(authFail(error));
});
}
}
//authReducer.js
import { FETCH_AUTH_SUCCESS, FETCH_AUTH_FAILURE, FETCH_AUTH_CLEAR } from '../actions/authAction'
export function authReducer (state = {}, action) {
//console.log('reducer act', action)
switch (action.type) {
case FETCH_AUTH_SUCCESS:
return {...state, data: action.payload, isLogged: true};
case FETCH_AUTH_FAILURE:
return {...state, data: action.payload, isLogged: false};
case FETCH_AUTH_CLEAR:
return {...state, data: action.payload, isLogged: false};
default:
return {...state}
}
}
根据“史蒂文·丹尼尔·安德森”的回答
"
const user = localStorage.getItem('user')
if(user){
//Set the state authenticated to true;
store.dispatch({
type:AUTH_USER
})
}
"
更像
const user = localStorage.getItem('user')
if(user){
//Set the state authenticated to true;
authSuccess(user)
}
或者在我的操作中创建一个像这样的新函数
export function fetchResumeAuth(data) {
dispatch(authSuccess(data));
}
然后在用户检查中——哪个将被放置在 router.js 中?
const user = localStorage.getItem('user')
if(user){
//Set the state authenticated to true;
fetchResumeAuth(user)
}
最佳答案
您可以使用 localStorage 在浏览器中保存用户:
localStorage.setItem('user',user)
在您的操作创建者中用于登录。
然后创建一个reducer,如果用户已通过身份验证,则将状态设置为true;如果没有,则将状态设置为false,如下所示:
import { AUTH_USER, UNAUTH_USER, ERROR } from '../actions/types'
export default function (state={}, action){
switch(action.type){
case AUTH_USER:
return { ...state, authenticated: true }
case UNAUTH_USER:
return { ...state, authenticated: false }
default:
return state
}
}
如果每次重新加载页面时都对用户进行身份验证,最后一部分将在 index.js 文件中进行验证:
const user = localStorage.getItem('user')
if(user){
//Set the state authenticated to true;
store.dispatch({
type:AUTH_USER
})
}
注意:您只需在任何 View 中使用 localStorage.getItem('user')
即可访问用户。
关于Reactjs、Redux - redux-persist,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46208242/
在 Spring-MVC 应用程序中,我尝试使用 validator 。我将注释 @NotEmpty 和 @Email 放在我的实体之一上,当我尝试验证它时,出现此错误: java.lang.NoSu
网络是我硕士学位的最后一门类(class)。我确实有一个关于如何计算非持久、持久和持久流水线的 http 往返时间的问题。 在花了无数小时阅读有关该问题、从其他大学下载笔记甚至搜索 youtube 视
让我们考虑典型的 订购 和 订单商品 例子。假设 订单商品 是 的一部分订购 聚合,只能通过订单添加。所以,添加一个新的 订单商品 到 订购,我们必须通过 Repository 加载整个 Aggreg
// lookup existing user & set a currently null child entity (ContactInfo) user.setContactInfo(contac
我正在尝试关注 this tutorial .我想我不是从使用可下载项目开始,而是从我之前做过的一个简单的“spring MVC - Maven - eclipse”项目开始。这个项目运行良好。 因此
我正在使用打开 Kubernetes 选项的 docker 应用程序运行 mac OSX Catalina。我使用以下 yaml 和命令创建了一个 PersistentVolume。 apiVersi
假设我有一个类 Employee和一个类Company其中包含 Employee 的 LinkedList对象,我想编写一个添加 Employee 的方法到特定的数据库Company 。我创建了一个新
我实际上正在将我们应用程序的所有组件更新到最新版本。因此,除其他外,我将从 eclipselink-2.5.0 升级到 eclipselink-2.7.3,并从 Tomcat 7 升级到 TomEE。
我试图遵循《用GlassFish 3开始Java EE 6平台》一书第2章中的示例。我正在Windows中使用cmd中的EclipseLink,Derby和Maven。我真的不知道这一点,将不胜感激!
我只是看看ClassGuard (虽然我知道一些 objection )。 但是我得到了 javax.persistence.PersistenceException: [PersistenceUni
我的印象是,如果我们使用持久字段,就不需要 getter 方法,因为实体管理器直接引用实例变量。但是,当我从实体中删除 getter 和 setter 方法以具有持久字段时,未从数据库中检索到相应实例
我正在 Eclipse 中使用 Servlet、JPA、EJB 和 JBoss 进行项目。正如您在我的主题标题中看到的,我的 persistence.xml 文件有错误,但我不知道是哪个:
我已经尝试了一个星期或更长时间来让我的状态在 react native Android 应用程序中持续存在,但在重新水化后状态始终具有初始值。如果我使用 Redux devtools 检查 ASync
什么时候应该坚持,什么时候应该补充水分?命名约定非常困惑,因为作者几乎没有提到它们在 redux-persist 的上下文中的含义。 . 最佳答案 在不真正了解图书馆的情况下: persist = 将
我正在尝试按照老师文档中提供的信息设置一个简单的 jpa 2.0 项目。我已经处理这个问题好几个小时了,但无论我做什么,当我尝试创建 EntityManagerFactory 时,我总是遇到这个异常:
我有一个 Maven 项目,我将其转换为现在可与 Maven 一起使用的 JPA 项目。我的persistence.xml如下: My Persistence Unit
我正在使用 Netbeans 6.8 并构建简单的 Maven Web 应用程序项目。 为持久实体创建实体和主文件 [也创建持久单元] 并使用 EclipsLink。 但是当我运行主文件时出现这个错误
我是 Kubernetes 的新手,我很难理解 Kubernetes 中持久存储背后的整个想法。 这就足够了吗,或者我必须创建持久卷,如果我只部署这两个对象而不创建 PV 会发生什么情况? 存储应该在
我正在尝试使用 JPA 为我目前参与的 Java-EE 项目设置持久性,并且我遇到了许多配置问题。目前,我已经在 persistence.xml 中定义了一个 RESOURCE_LOCAL 持久性单元
Akka 持久性查询通过提供一个通用的基于异步流的查询接口(interface)来补充 Persistence,各种日志插件可以实现该接口(interface)以公开它们的查询功能。 这是来自 akk
我是一名优秀的程序员,十分优秀!