Local Storage存储用户登录信息(token+id)
auth.js——action
在auth的action中设置判断是否登入的函数;
1.判断localstorage中是否登入;
2.计算自动登出的时间(结束时间-当前时间);
export const authCheckState = ()=>{
return dispatch=>{
const token = localStorage.getItem('token');
if(!token){
dispatch(logout());
}else{
const expirationDate = new Date(localStorage.getItem('expirationDate'));
//从ls中得到的为string,需要用new date转为时间
if(expirationDate > new Date()){ //可以登入
const userId = localStorage.getItem('userId');
dispatch(authSuccess(token,userId));
dispatch(checkAuthTimeout(expirationDate.getTime()-new Date().getTime()));
}else { //否则就登出
dispatch(logout());
//传入自动登出的剩余时间
};
};
};
};
异步获取用户信息时——保存用户的token,token过期时间,用户名
axios.post(url,authData)
.then(response=>{
//设定localstorage(包括token和timeout)
const expirationData = new Date(new Date().getTime() + response.data.expiresIn * 1000);//将s变为ms
localStorage.setItem('token',response.data.idToken); //保存token
localStorage.setItem('expirationDate',expirationData);
localStorage.setItem('userId',response.data.localId);
//保存id
console.log(response);
dispatch(authSuccess(response.data.idToken,response.data.localId));
//同时设置登录计时
dispatch(checkAuthTimeout(response.data.expiresIn));
})
.catch(err=>{
dispatch(authFail(err.response.data.error)); //axios提供的err调用方法
});
登出时,清空localstorage中的token,用户名,登出时间
export const logout=()=>{
//退出时清空localstorage
localStorage.removeItem('token');
localStorage.removeItem('expirationDate');
localStorage.removeItem('userId');
return {
type: actionTypes.AUTH_LOGOUT
};
};
每次刷新都会调用app.js,所以在app.js的didmount中调用此check函数
import React, { Component } from 'react';
import {Route, Switch} from 'react-router-dom';
import Layout from './hoc/Layout/Layout';
import BurgerBuilder from './containers/BurgerBuilder/BurgerBuilder';
import Checkout from './containers/Checkout/Checkout';
import Orders from './containers/Orders/Orders';
import Logout from './containers/Auth/Logout/Logout';
import Auth from './containers/Auth/Auth';
import {connect} from 'react-redux';
import * as actions from './store/actions/index';
//每次route都会loaded——可用于判断auth状态
class App extends Component {
componentDidMount(){
this.props.onTryAutoSignup();
};
render () {
return (
<div>
<Layout>
<Switch>
<Route path="/checkout" component={Checkout}/>
<Route path="/orders" component={Orders}/>
<Route path="/auth" component={Auth}/>
<Route path="/logout" component={Logout}/>
<Route path="/" exact component={BurgerBuilder}/>
</Switch>
</Layout>
</div>
);
}
}
const mapDispatchToProps = dispatch=>{
return {
onTryAutoSignup: ()=>dispatch(actions.authCheckState())
};
};
export default connect(null,mapDispatchToProps)(App);
使用refreshed tokoen可让用户永不过期,但会有安全隐患
将route根据isauth设置
app.js
import React, { Component } from 'react';
import {Route, Switch,Redirect} from 'react-router-dom';
import Layout from './hoc/Layout/Layout';
import BurgerBuilder from './containers/BurgerBuilder/BurgerBuilder';
import Checkout from './containers/Checkout/Checkout';
import Orders from './containers/Orders/Orders';
import Logout from './containers/Auth/Logout/Logout';
import Auth from './containers/Auth/Auth';
import {connect} from 'react-redux';
import * as actions from './store/actions/index';
//每次route都会loaded——可用于判断auth状态
class App extends Component {
componentDidMount(){
this.props.onTryAutoSignup();
};
render () {
//设置不同状态下能访问的页面
let routes = (
<Switch>
<Route path="/auth" component={Auth}/>
<Route path="/" exact component={BurgerBuilder}/>
<Redirect to='/'/>
</Switch>
);
if(this.props.isAuthenticated){
routes = (
<Switch>
<Route path="/checkout" component={Checkout}/>
<Route path="/orders" component={Orders}/>
<Route path="/logout" component={Logout}/>
<Route path="/" exact component={BurgerBuilder}/>
<Redirect to='/'/>
</Switch>
);
};
return (
<div>
<Layout>
{routes}
</Layout>
</div>
);
}
}
const mapStateToProps = state=>{
return{
isAuthenticated: state.auth.token !== null
};
};
const mapDispatchToProps = dispatch=>{
return {
onTryAutoSignup: ()=>dispatch(actions.authCheckState())
};
};
export default connect(mapStateToProps,mapDispatchToProps)(App);
这样即使输入指定path,也无法访问到该页面;
fetchorders设置权限,只fetch本userid的orders
登陆时设置保存userid+post时上传userid到database
const order = {
ingredients: this.props.ings,
price: this.props.price,
orderData:formData,
userId:this.props.userId //传入userid
}
设置fetchoerder时的queryparams
export const fetchOrders= (token,userId)=>(dispatch)=>{ //actioncreator函数——返回一个action
dispatch(fetchOrdersStart());
//加入auth操作
const queryParams = '?auth='+token+'&orderBy="userId"&equalTo="'+userId+'"';
//可被firebase理解的query
axios.get('/orders.json'+queryParams)
.then(res=>{
const fetchOrders=[];
for(let key in res.data){
fetchOrders.push({
...res.data[key],
id:key
});
}
dispatch(fetchOrdersSuccess(fetchOrders));
})
.catch(error=>{
dispatch(fetchOrdersFailed(error));
});
};
设置database的rules(firebase)