React Project: Step11 Auth

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)
在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值